home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / chasm407.arc / CHASM.DOC < prev    next >
Text File  |  1987-01-10  |  164KB  |  6,463 lines

  1.  
  2.  
  3.                                            (tm)
  4.                                       CHASM
  5.  
  6.                                  Cheap Assembler
  7.                           for the IBM Personal Computer
  8.  
  9.                                   User's Manual
  10.                             (c) 1985 by David Whitman
  11.                                   Version 4.07
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.     David Whitman
  37.     P.O. Box 1157
  38.     North Wales, PA 19454
  39.     (215) 641-7522 (days)
  40.     (215) 234-4084 (evenings)
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.                        Table of Contents
  67.  
  68.  
  69.  
  70.     Why CHASM?..................................................1
  71.     What can CHASM do?..........................................2
  72.     What WON'T it do?...........................................3
  73.     System Requirements.........................................4
  74.     Advanced and Subset CHASM...................................5
  75.     Modifying CHASM's I/O Defaults..............................6
  76.     Syntax.....................................................11
  77.     Labels.....................................................13
  78.     Operands...................................................16
  79.     Operand Expressions........................................22
  80.     Resolution of Ambiguities..................................25
  81.     Pseudo-Operations..........................................29
  82.     Macros.....................................................38
  83.     Structures.................................................48
  84.     8087 Support...............................................52
  85.     Outside the Program Segment................................54
  86.     Running CHASM..............................................55
  87.     Error and Diagnostic Messages..............................59
  88.     Execution of Assembled Programs............................64
  89.     Notes for Those Upgrading to This Version of CHASM.........75
  90.     Miscellaneous and A Word From Our Sponsor..................78
  91.     =============================================================
  92.     Appendix A: 8088 Mnemonic List.............................83
  93.     Appendix B: 8087 Mnemonic List.............................85
  94.     Appendix C: Differences Between CHASM and TOA..............86
  95.     Appendix D: Description of Files...........................90
  96.     Appendix E: Bug Reporting Procedure........................91
  97.     Appendix F: Using CHASM on "Compatible" Systems............92
  98.     Advanced Version Order Form................................94
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.                                                                     1
  128.  
  129.     >>Why CHASM?<<
  130.  
  131.     Why go to the trouble to write an assembler, when one already
  132.     exists?  The IBM Macro Assembler is a very powerful software tool
  133.     available off the shelf.  It supports features such as macros,
  134.     multiple segments, and linking to external procedures.
  135.  
  136.     Unfortunately, the cost of all this power is complexity. The
  137.     Macro Assembler is so complicated that IBM warns beginners it is
  138.     only suitable for "experienced assembly language programmers".
  139.  
  140.     For most users, this sophistication is more of a hindrance than
  141.     an aid.  Even when writing short, simple programs, the user is
  142.     saddled with a set of confusing pseudo-ops only appropriate for
  143.     large, multi-segment programs.  Producing a fast loading
  144.     executable file requires running three separate programs (MASM,
  145.     LINK and EXE2BIN) before you can get down to testing.
  146.  
  147.     The macro assembler is totally unsuitable for use with BASIC.
  148.     Although it is *possible* to produce machine language BASIC
  149.     subroutines with the Macro Assembler, the process is incredibly
  150.     convoluted and confusing.
  151.  
  152.     To top it all off, the Macro Assembler costs an overpriced $125.
  153.  
  154.     CHASM is, I hope, a more reasonable compromise between power and
  155.     accessibility.  CHASM is simple to use and understand.  Unlike
  156.     the Macro Assembler, CHASM doesn't require a second LINK step to
  157.     produce a working program.  CHASM also produces fast loading
  158.     programs without the use of the utility EXE2BIN.
  159.  
  160.     CHASM supports several different simple mechanisms for getting
  161.     machine language routines into BASIC and Turbo Pascal, the two
  162.     most popular languages for the IBM Personal Computer.
  163.  
  164.     Finally, the suggested payment for CHASM is a modest $40.
  165.  
  166.     A Note for Beginners:
  167.  
  168.     Before going on, you might find it useful to print and read the
  169.     file PRIMER.DOC, included on your CHASM disk.  PRIMER is a gentle
  170.     introduction to assembly language, which will teach you some of
  171.     the vocabulary and key concepts you will need to start out with.
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.                                                                     2
  194.  
  195.     >>What can CHASM do?<<
  196.  
  197.     CHASM is a tool for translating assembly language into the native
  198.     machine language of the 8088 microprocessor.  Using CHASM, you
  199.     can write down easy to remember "mnemonics" which are then
  200.     converted into the relatively incomprehensible series of ones and
  201.     zeros that your PC prefers to work with.
  202.  
  203.     In addition to simple mnemonic translation (such as provided by
  204.     the mini-assembler in DEBUG), CHASM provides a great many
  205.     "convenience" features which make writing machine language much
  206.     easier.
  207.  
  208.     CHASM allows you to define labels for branching, rather than
  209.     requiring you to figure out offsets or addresses to jump to.
  210.     CHASM also lets you give symbolic names to any constants or
  211.     memory locations you use, to make your program easier to
  212.     understand.
  213.  
  214.     You can instruct CHASM to make your file "BLOADable" so that
  215.     BASIC can load it as a subroutine.   A utility is also provided
  216.     to convert machine language into BASIC "DATA" statements, so that
  217.     BASIC can "POKE" routines into memory.  Similarly, for Turbo
  218.     Pascal CHASM can produce external procedures and functions, or a
  219.     file of Turbo "INLINE" statements.
  220.  
  221.     CHASM has intelligent error and diagnostic messages which guide
  222.     you in correcting mistakes and ambiguities in your program.  A
  223.     nicely formatted listing is produced during assembly, to help
  224.     during debugging.
  225.  
  226.     In general, CHASM is designed to eliminate much of the confusion
  227.     and dirty work involved in writing machine language for the IBM
  228.     PC.
  229.  
  230.     Using CHASM, you can produce:
  231.  
  232.        1. Lightning fast "stand-alone" programs.
  233.  
  234.        2. Machine language subroutines for BASIC programs, both
  235.           interpreted and compiled.
  236.  
  237.        3. Machine language procedures and functions for Turbo Pascal.
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.                                                                     3
  260.  
  261.     >>What WON'T it do?<<
  262.  
  263.     In the interest of simplicity, CHASM has the following
  264.     restrictions:
  265.  
  266.     1. Multiple segment definitions are not allowed. CHASM assumes
  267.        that your entire program fits in one segment, that the cs, ds,
  268.        and es registers all point to this same segment, and that the
  269.        ss register points to a valid stack area.  An equivalent
  270.        statement is that CHASM produces COM files, not EXE files.
  271.  
  272.     2. Linking to Microsoft languages is not supported.  You can't
  273.        use CHASM to produce object modules for use with IBM/Microsoft
  274.        Pascal or FORTRAN.
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.                                                                     4
  326.  
  327.     >>System Requirements<<
  328.  
  329.     Minimum system requirements to use CHASM are:
  330.  
  331.          IBM PC or true compatible (must emulate IBM BIOS)
  332.          128K of memory            (192K for IBM PCjr)
  333.          1 disk drive
  334.          80 column display
  335.          DOS 2.0 or later.
  336.  
  337.     Note the DOS 2 requirement.  To provide *true* DOS 2 support, it
  338.     was necessary to give up DOS 1 compatibility.  If you're still
  339.     using DOS 1, you'll need to upgrade to DOS 2.0 or later to use
  340.     CHASM.
  341.  
  342.     Adding more memory will allow you to assemble larger programs.
  343.     CHASM can take advantage of all available memory, up to a
  344.     megabyte.
  345.  
  346.     CHASM will run faster if your source files and object files are
  347.     on a hard disk or RAM disk.
  348.  
  349.     If you have a non-IBM computer, please read about the /VIDEO
  350.     switch in "Modifying CHASM's I/O Defaults" and also the appendix
  351.     titled "Using CHASM on Compatible Systems"
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.                                                                     5
  392.  
  393.     >>Advanced and Subset CHASM<<
  394.  
  395.     CHASM is available in two flavors, Advanced and Subset.
  396.     The two versions vary in their capabilities and method of
  397.     distribution.
  398.  
  399.     The subset version is the budget release.  It may be freely
  400.     copied by individuals as "user-supported" software, and is
  401.     available from user groups and bulletin boards across the
  402.     country.  Every time the subset runs, it prints a banner page
  403.     suggesting a payment of $40 to the author.  As its name
  404.     suggests, Subset CHASM does not support all the features of
  405.     Advanced CHASM.
  406.  
  407.     Advanced CHASM is the deluxe release.  It runs twice as fast, and
  408.     has a number of features not supported by the subset:
  409.  
  410.           macros
  411.           conditional assembly
  412.           8087 support
  413.           include files
  414.           operand expressions
  415.           structures
  416.  
  417.     Advanced CHASM is only available directly from Whitman Software.
  418.     Users who make the suggested $40 payment receive an upgrade to
  419.     Advanced CHASM.  Details, and an order blank are given at the
  420.     end of this document.
  421.  
  422.     Throughout this document, features supported only by the
  423.     advanced version will be marked as follows:
  424.  
  425.       ==>Advanced version only.
  426.  
  427.     Attempts to use these features in the subset version will
  428.     generally result in error messages, with the advanced feature
  429.     otherwise being ignored; however, unpredictable behavior could
  430.     result in some instances.
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.                                                                     6
  458.  
  459.     >>MODIFYING CHASM'S I/O DEFAULTS<<
  460.  
  461.     CHASM supports the use of a configuration file, which can be used
  462.     to override some of CHASM's I/O defaults.  If you are willing to
  463.     accept CHASM's defaults, you may skip this section - on most
  464.     systems, CHASM will work perfectly well without the file
  465.     described below.
  466.  
  467.     The configuration process involves supplying a text file named
  468.     CHASM.CFG on your default drive.  You can create this file with
  469.     any text editor or word processor.
  470.  
  471.     You have some freedom in where you put the configuration file.
  472.     If CHASM.CFG is not found in the current directory, CHASM will
  473.     also try the following paths:
  474.  
  475.           \CHASM\CHASM.CFG
  476.           \CHASM.CFG
  477.  
  478.     The file should contain a series of text "switches" of the
  479.     following form:
  480.  
  481.     /SWITCH, xx [, yy, zz,...]
  482.  
  483.     Where "/SWITCH" is a reserved word, listed below, and xx, yy, zz
  484.     are numbers.  The brackets around yy and zz indicate that these
  485.     numbers are optional - don't put brackets in CHASM.CFG.
  486.  
  487.     Each switch should start a new line, and the switch and each of
  488.     the numbers should separated by one or more blanks or commas.
  489.  
  490.     The following switches are implemented:
  491.  
  492.     /VIDEO      Video access method.  With this switch, you can
  493.                 control the method CHASM uses to write data on your
  494.                 video screen.  Three settings are currently
  495.                 supported:
  496.  
  497.                 /VIDEO 0  Direct write to screen memory.
  498.  
  499.                 /VIDEO 1  Direct write to screen memory, but only
  500.                           during the horizontal retrace interval.
  501.  
  502.                 /VIDEO 2  Write using BIOS calls.
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.                                                                     7
  524.  
  525.     /VIDEO      (continued) In general, the lower a number you
  526.                 specify for /VIDEO, the faster CHASM will run.
  527.  
  528.                 /VIDEO 0 is the fastest mode, and is intended for use
  529.                 with either the IBM monochrome display adapter or the
  530.                 EGA adapter.  You can use /VIDEO 0 with the CGA
  531.                 adapter, but some annoying "snow" and flicker may
  532.                 result.
  533.  
  534.                 /VIDEO 1 is intended for use with the CGA adapter.
  535.                 It is almost as fast as /VIDEO 0, and the snow is
  536.                 eliminated.  /VIDEO 1 is CHASM's default mode.
  537.  
  538.                 /VIDEO 2 is intended for non-IBM systems that emulate
  539.                 the IBM BIOS, but have significantly different screen
  540.                 hardware.  If you have trouble running CHASM on a
  541.                 "compatible" system, try setting /VIDEO 2.  Use of
  542.                 /VIDEO 2 will slow CHASM down significantly.
  543.  
  544.     /FG         Foreground color.  Users with color monitors may
  545.                 select a foreground color from the following list:
  546.  
  547.                 0    Black               8    Gray
  548.                 1    Blue                9    Light Blue
  549.                 2    Green              10    Light Green
  550.                 3    Cyan               11    Light Cyan
  551.                 4    Red                12    Light Red
  552.                 5    Magenta            13    Light Magenta
  553.                 6    Brown              14    Yellow
  554.                 7    White              15    High Intensity White
  555.  
  556.                 Example: (Magenta)
  557.  
  558.                 /FG 5
  559.  
  560.     /BG         Background color.  Selections 0-7 above are
  561.                 available. Example: (Cyan)
  562.  
  563.                 /BG, 3
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.                                                                     8
  590.  
  591.     /132        Printer 132 column mode.  The numbers following this
  592.                 switch are the ASCII codes for the characters which
  593.                 cause your printer to go into condensed mode.  You
  594.                 may specify as many characters as you like.  If you
  595.                 don't provide this switch, CHASM will truncate source
  596.                 lines in listings to avoid going over 80 columns. You
  597.                 can also include characters to activate any special
  598.                 features of your printer you want CHASM to use during
  599.                 printing.  Example: (for IBM printer)
  600.  
  601.                 /132, 15
  602.  
  603.     /80         Printer 80 column mode.  Similar to /132, but the
  604.                 numbers represent the characters to return your
  605.                 printer to normal.  Include the codes for any
  606.                 characters you want CHASM to send to your printer
  607.                 before returning you to DOS.  The following example
  608.                 turns off condensed mode and causes a Form Feed on
  609.                 the IBM printer:
  610.  
  611.                 /80, 18, 12
  612.  
  613.     /FF         Formfeed.  A value of zero tells CHASM that your
  614.                 printer doesn't recognize ASCII 12 as a formfeed
  615.                 command.  Any other value, and CHASM assumes that
  616.                 formfeeds will be recognized.  The default is no
  617.                 formfeed character.
  618.  
  619.                 If /FF is off, CHASM will simulate formfeeds with a
  620.                 series of linefeeds.  However, most printers respond
  621.                 quicker to a formfeed than to multiple line feeds, so
  622.                 set /FF on if possible.  Example: (on)
  623.  
  624.                 /FF 1
  625.  
  626.     /PAGELEN    CHASM assumes that there are 66 lines to each printed
  627.                 page.  If you use different sized paper, enter the
  628.                 number of lines per page after this switch.
  629.                 Example: (European standard)
  630.  
  631.                 /PAGELEN 72
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.                                                                     9
  656.  
  657.     /LINES      By default, CHASM will print 58 lines on each printed
  658.                 page, then skip over the perforation to the next
  659.                 page.  You can change this number to suit your paper
  660.                 and personal taste.  Example:
  661.  
  662.                 /LINES 50
  663.  
  664.     /BEEP       Enables/Disables audible warning when errors are
  665.                 discovered in your source program.  A value of zero
  666.                 turns off beeping, anything else turns it on. The
  667.                 default is on.  Example: (off)
  668.  
  669.                 /BEEP 0
  670.  
  671.      /DWIDTH    When listing to a disk file, CHASM normally truncates
  672.                 listing lines to 80 columns to prevent wrap-around
  673.                 when viewing the file.  In some instances, such as
  674.                 disk-based print spooling with DOS's PRINT utility,
  675.                 you may wish to override this truncation.  You can
  676.                 enter a new truncation limit after this switch. 
  677.                 Example: (128 column lines)
  678.  
  679.                 /DWIDTH 128
  680.  
  681.      /DPAGE     For easier scanning, listings sent to disk files do
  682.                 not normally contain page breaks.   If you want to
  683.                 produce printable listing files, you can turn on page
  684.                 breaks by setting /DPAGE to any value other than
  685.                 zero.  Example: (page breaks on)
  686.  
  687.                 /DPAGE 1
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721.                                                                    10
  722.  
  723.       /PATH     Path Strategy.  Affects the way CHASM constructs the
  724.                 default file names for list and object files.  If
  725.                 /PATH is set to 0 (the default), any drive or path
  726.                 specified on the source file name will be included in
  727.                 the default file names.  If /PATH is set to anything
  728.                 else, path and drive info are removed, thus putting
  729.                 the default list and object files in the current
  730.                 directory of the logged drive.  The following table
  731.                 shows how this works:
  732.  
  733.                 /PATH | Source filename   | Default object file
  734.                 ------|-------------------|-------------------------
  735.                    0  | a:\chasm\test.asm |   a:\chasm\test.com
  736.                    1  | a:\chasm\test.asm |   test.com
  737.  
  738.                 /PATH only affects how the default file names are
  739.                 constructed - CHASM won't edit filenames that you
  740.                 explicitly type in.
  741.  
  742.      /TIMER     Enables/Disables reporting of total assembly time. A
  743.                 value of 0 turns off timing, anything else turns it
  744.                 on.  The default is off.  This switch is used
  745.                 internally at Whitman Software to benchmark new
  746.                 versions of CHASM.
  747.  
  748.     A sample CHASM.CFG file, suitable for use with the IBM dot matrix
  749.     printer, is included on your CHASM distribution disk.
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.                                                                    11
  788.  
  789.     >>Syntax<<
  790.  
  791.     CHASM accepts a standard DOS text file for input.  In this
  792.     context, "standard DOS text file" means:
  793.  
  794.         1. Lines are terminated with a CR/LF pair.
  795.  
  796.         2. The end of the file is marked with an EOF marker (cntl-Z).
  797.  
  798.     Virtually every word processor or editor produces files which
  799.     meet these criteria.  Some word processors have to be in a
  800.     special mode to produce standard DOS files.  (For example, in
  801.     WordStar, you have to be in "non-document" mode.) The user's
  802.     manual for your editor should inform you if any special mode
  803.     needs to be activated.
  804.  
  805.     Some users have reported problems with the user-supported word
  806.     processor PC-Write.  Under certain circumstances, older
  807.     versions of PC-Write can produce lines ending with just a LF
  808.     (violation of rule 1) or files which aren't terminated with an
  809.     EOF marker (violation of rule 2).  If you use PC-Write, make sure
  810.     you have the latest version.
  811.  
  812.     Lines may be any combination of upper and lower case characters.
  813.     CHASM does not distinguish between the two cases: everything
  814.     except single quoted strings are automatically converted to upper
  815.     case during the parsing process.  Thus, BUFFER, Buffer, buffer,
  816.     and bUFFer all refer to the same symbol.
  817.  
  818.     The characters  blank ( ), comma (,), single quote (')
  819.     semi-colon (;) and TAB are reserved, and have special meaning to
  820.     CHASM (see below).
  821.  
  822.     Each line must be no more than 80 characters long and have the
  823.     following format:
  824.  
  825.        Label Operation Operand(s) ;comment
  826.  
  827.     The different fields of an input line are separated by the
  828.     delimiters blank ( ), comma (,) or TAB.  Any number of any
  829.     delimiter may be used to separate fields.
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.                                                                    12
  854.  
  855.     Explanation of Fields:
  856.  
  857.     Label: A label is a string of characters, beginning in column 1.
  858.        Depending on the operation field, the label might represent a
  859.        program location for branching, a memory location, or a
  860.        numeric constant (see the section titled "Labels" for more on
  861.        this topic). To ensure that CHASM can distinguish between
  862.        labels and numeric constants, the first character of a label
  863.        must *not* be a number (0-9), plus sign (+) or minus sign(-).
  864.        Anything beginning in column 1, except a comment, is
  865.        considered a label.
  866.  
  867.     Operation: Either a pseudo-op (see the section with the same
  868.        name) or an instruction mnemonic as defined in "The 8086
  869.        Book" by Rector and Alexy.  A list of acceptable mnemonics is
  870.        given in Appendix A.
  871.  
  872.        Note 1: Except as modified below,"The 8086 Book" is the
  873.           definitive reference for use with CHASM.
  874.  
  875.        Note 2: There are several ways to resolve some ambiguities in
  876.           8086 assembly language.  Please read page 3-285 of The 8086
  877.           Book, and "Resolution of Ambiguities" in this document.
  878.  
  879.     Operand(s): A list of one or more operands, as defined in
  880.        the section titled "Operands", separated by delimiters.
  881.  
  882.     Comment: Any string of characters, beginning with a semicolon
  883.        (;). Anything to the right of a semicolon will be ignored by
  884.        CHASM.
  885.  
  886.     Note that except for the case of an operation which requires
  887.     operands, or the EQU pseudo-op which requires a label, all of the
  888.     fields are optional.  The fields MUST appear in the order shown.
  889.  
  890.  
  891.  
  892.  
  893.  
  894.  
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.                                                                    13
  920.  
  921.     >>Labels<<
  922.  
  923.     The symbol in the label field of an input line can be interpreted
  924.     in four different ways by CHASM:
  925.  
  926.       1. A program location which may be branched to.
  927.  
  928.       2. A memory location for data storage.
  929.  
  930.       3. An equated symbol, which takes the place of a numeric
  931.          constant.
  932.  
  933.       4. A macro name, which takes the place of a series of
  934.          frequently used source code lines.
  935.  
  936.     The default interpretation of a symbol is a program location for
  937.     branching.  This default is modified by the presence of one of
  938.     the following pseudo-ops in the instruction field:
  939.  
  940.     DB, DM, DS, or DW:
  941.  
  942.           Normal:  The symbol is a memory location.
  943.  
  944.           In a Structure: The symbol is a numeric constant.
  945.  
  946.     EQU:
  947.  
  948.           Normal:  The symbol is a numeric constant.
  949.  
  950.           Memory Option:  The symbol is a memory location.
  951.  
  952.     MACRO: 
  953.          The symbol is a macro name.
  954.  
  955.     A given symbol may have only ONE of the above interpretations!
  956.     Attempts to branch into a memory location or an equated symbol
  957.     will result in error messages.  Similarly, CHASM will not allow
  958.     you to treat program code as a data area.  Examples:
  959.  
  960.     TEXT DB  'Hit any key when ready'  ;memory location
  961.          MOV  AL,TEXT                  ;ok
  962.          JMP  TEXT                     ;wrong!
  963.     LOOP MOV  AX,CX                    ;program location
  964.          JMP  LOOP                     ;ok
  965.          MOV  AX, LOOP                 ;wrong!
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.                                                                    14
  986.  
  987.     If for some arcane reason you *need* to branch into a data area,
  988.     you can fool CHASM by placing a label on an otherwise blank line,
  989.     immediately before the data area.  Example:
  990.  
  991.           JNZ NPU
  992.           RET
  993.     NPU                                ;dummy label for jump
  994.           DB  D8H, 00H                 ;an 8087 instruction
  995.  
  996.     If you have a masochistic urge to crash your system by writing
  997.     self-modifying code, there are at least two ways you can defeat
  998.     CHASM's injunction against using program code as a data area.
  999.  
  1000.     The first way is to use DS to declare zero bytes of storage
  1001.     immediately before the code you want to access.  A label on the
  1002.     null DS will have the same offset as the immediately following
  1003.     code.  Example:
  1004.  
  1005.            MOV   JUNK1, 9090         ;change endless loop to NOP
  1006.     JUNK1  DS    0
  1007.     JUNK   JMP  JUNK
  1008.  
  1009.     A sneakier approach is to load the OFFSET of a program
  1010.     location into a register, then use the register for indirect
  1011.     addressing. Using the optional displacement field, you can even
  1012.     address the middle of an instruction.  Examples:
  1013.  
  1014.            MOV   BX, OFFSET(CALL)
  1015.            MOVB  1[BX], 00H          ;change interrupt number in code
  1016.     CALL   INT   0
  1017.  
  1018.     In general, I cannot recommend trying to get around CHASM's type
  1019.     restrictions.  If you find yourself in a situation where it
  1020.     seems necessary to fool CHASM, there's probably a safer, more
  1021.     direct way to legally program what you're trying to accomplish.
  1022.  
  1023.     Labels can be up to 80 characters long, but only the first 15
  1024.     characters are significant.  For example, CHASM considers the
  1025.     following labels identical:
  1026.  
  1027.        VERYLONGLABELOVER15CHARACTERS
  1028.        VERYLONGLABELOVER
  1029.  
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.                                                                    15
  1052.  
  1053.     To avoid ambiguity, a given string can legally appear in the
  1054.     label field of only ONE statement.  If the same string appears on
  1055.     more than one instruction, all instances after the first will
  1056.     receive an error message.  Remember that labels are only
  1057.     significant to 15 characters, and if the first 15 characters are
  1058.     identical, an error will occur.
  1059.  
  1060.     TWO   EQU  '2'      ;first use is ok
  1061.     TWO   PROC FAR      ;wrong! symbol already defined
  1062.  
  1063.     CHASM has a number of reserved strings which are "predefined" in
  1064.     the symbol table, and will generate an error message if used as
  1065.     labels.  All the register names are reserved, as are the indirect
  1066.     address mode combinations.  The only other reserved strings are
  1067.     the words "NEAR" and "FAR", and the symbol "$". Examples:
  1068.  
  1069.     AX   MOV  AX, DX      ;wrong! (register name)
  1070.     [DI] ADD  AX, BX      ;wrong! (indirect address)
  1071.     FAR  CALL GETINPUT    ;wrong! (reserved word)
  1072.     $    SUB  AX, DX      ;wrong! (reserved word)
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080.  
  1081.  
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091.  
  1092.  
  1093.  
  1094.  
  1095.  
  1096.  
  1097.  
  1098.  
  1099.  
  1100.  
  1101.  
  1102.  
  1103.  
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.                                                                    16
  1118.  
  1119.     >>Operands<<
  1120.  
  1121.     The following operand types are allowed.
  1122.  
  1123.     1. Immediate data: A number, stored as part of the program's
  1124.        object code.  Immediate data are classified as either byte,
  1125.        expressible as an 8 bit binary integer; or word, expressible
  1126.        as a 16 bit binary integer.  If context requires it, CHASM
  1127.        will left-pad byte values with zeroes to convert them to word
  1128.        values.  Attempts to use a word value where only a byte will
  1129.        fit will cause an error message to be printed.
  1130.  
  1131.        Immediate data may be represented in 9 ways:
  1132.  
  1133.           A. An optionally signed decimal number in the range -32768
  1134.              to 32767.  Examples:
  1135.  
  1136.              MOV AL, 21
  1137.              MOV BX, -6300
  1138.  
  1139.           B. A series of up to 4 hex digits, followed by the letter
  1140.              H.  The first digit must be non-alphabetic, i.e. in the
  1141.              range 0-9, to allow CHASM to distinguish between numbers
  1142.              and symbols. If necessary, a leading zero, which does
  1143.              not count in the four allowed digits, may be added to
  1144.              fulfill the non-alphabetic condition.
  1145.  
  1146.              If the RADIX pseudo-op has been used to change the
  1147.              default number base to 16, the final H can optionally be
  1148.              omitted.  Examples:
  1149.  
  1150.              ADD   CX, 0B123H   ;leading zero required
  1151.              RADIX 16           ;change default number base
  1152.              ADD   DL, 12       ;same as 12H
  1153.  
  1154.          C.  A series of up to 16 binary digits, followed by the
  1155.              letter B.  Examples:
  1156.  
  1157.              MASK   EQU   00000111B
  1158.                     MOV   AL, 10000000B
  1159.  
  1160.  
  1161.  
  1162.  
  1163.  
  1164.  
  1165.  
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.                                                                    17
  1184.  
  1185.           D. A symbol representing types A, B or C above, defined
  1186.              using the EQU pseudo-op.  Examples:
  1187.  
  1188.              MASK EQU 10H
  1189.              MAX  EQU 1000
  1190.                   AND  CL,MASK
  1191.                   SUB  AX,MAX
  1192.  
  1193.           E. The offset of a label or storage location returned by
  1194.              the OFFSET operator.  OFFSET always returns a word
  1195.              value. OFFSET is used to get the address of a named
  1196.              memory location, rather than its contents.  Example:
  1197.  
  1198.                     MOV DI,OFFSET(BUFFER)
  1199.              BUFFER DS  0FFH
  1200.  
  1201.           F. The ASCII value of a printable character, represented by
  1202.              the character enclosed in single quotes (').  Thus, the
  1203.              following lines will generate the same object code:
  1204.  
  1205.                 MOV AL,41H  ;ascii code for 'A'
  1206.                 MOV AL,'A'
  1207.  
  1208.           G. When producing Turbo Pascal INLINE code, the function
  1209.              TURBO(x) assembles as 16 bit immediate data.
  1210.  
  1211.           H. ==>Advanced version only:
  1212.              Labels within structures become immediate operands whose
  1213.              values equal their offset within the structure.  See the
  1214.              section titled "Structures" for more detail and
  1215.              examples.
  1216.  
  1217.           I. ==>Advanced version only:
  1218.              The length of a structure, returned either by the LENGTH
  1219.              operator, or simply the structure's name.  See the
  1220.              section titled "Structures" for more detail and
  1221.              examples.
  1222.  
  1223.           J. An expression that evaluates out to type Immediate.
  1224.              Examples:
  1225.  
  1226.                     MOV AX, (3+2)*5 
  1227.                     MOV DX, MEMLOC1-MEMLOC2
  1228.  
  1229.              See the "Operand Expressions" section for more details.
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248.  
  1249.                                                                    18
  1250.  
  1251.     2. Register Operands
  1252.  
  1253.        A. An 8 bit 8088 register from the following list:
  1254.           AH    AL
  1255.           BH    BL
  1256.           CH    CL
  1257.           DH    DL
  1258.  
  1259.        B. A 16 bit 8088 register from the following list:
  1260.  
  1261.           AX   BX   CX   DX   SP   BP   SI   DI
  1262.  
  1263.        C. An 8088 segment register from the following list:
  1264.  
  1265.           CS   SS   DS   ES
  1266.  
  1267.        D. An 8087 stack register from the following list:
  1268.  
  1269.           ST ST(1) ST(2) ST(3) ST(4) ST(5) ST(6) ST(7)
  1270.  
  1271.           Note: ST can also be referenced as ST(0).
  1272.  
  1273.     3. Memory Operands: The contents of a memory location addressed
  1274.        by one of the following methods.  Note that none of the memory
  1275.        addressing options specifies the *size* of the operand.  8088
  1276.        instructions have word or byte sized operands, and 8087
  1277.        instructions can have word, short, long or temporary real
  1278.        operands.  See the section titled "Resolution of Ambiguities"
  1279.        for more on this topic.
  1280.  
  1281.        All memory operands can optionally be preceded with a segment
  1282.        override to specify the segment register to be used in
  1283.        accessing memory.  The override takes the form of a segment
  1284.        register, followed by a colon, followed by the memory operand.
  1285.        No intervening delimiters are allowed.  Examples:
  1286.  
  1287.             MOV AX, ES:[80H]   ;80H into the extra segment
  1288.             MOV CS:[DI], SI     ;indirect with DI in the code segment
  1289.  
  1290.        Segment overrides are also discussed in the section titled
  1291.        "Resolution of Ambiguities".
  1292.  
  1293.  
  1294.  
  1295.  
  1296.  
  1297.  
  1298.  
  1299.  
  1300.  
  1301.  
  1302.  
  1303.  
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.                                                                    19
  1316.  
  1317.        A. Direct Memory Address.
  1318.  
  1319.           1. A number or other immediate operand, enclosed in
  1320.              brackets, indicating an offset into the data segment.
  1321.              Example:
  1322.  
  1323.              BUFFER EQU 5A5AH
  1324.                     MOV BH, [BUFFER]
  1325.                     MOV [80H], DI
  1326.                     MOV AX, CS:[TURBO(I)]
  1327.  
  1328.           2. A symbol, defined to be a variable (i.e. a named memory
  1329.              location) using the EQU pseudo-op.  Example:
  1330.  
  1331.              FCB EQU [80H]
  1332.                  MOV DI,FCB
  1333.  
  1334.           3. A symbol, defined to be a variable by its use on a
  1335.              storage defining pseudo-op.  Examples:
  1336.  
  1337.                   MOV AX,FLAG
  1338.                   MOV DATE,BX
  1339.              FLAG DS 1
  1340.              DATE DB 31
  1341.  
  1342.           4. The special symbol '$'.  $ returns an address of value
  1343.              equal to the current setting of CHASM's location
  1344.              counter.  This address can be used as either a memory
  1345.              location or a program location for branching.  Used by
  1346.              itself, $ has little utility, but it is a very powerful
  1347.              tool when used in expressions.  Example:
  1348.  
  1349.                   MOV AX, $+4    ;get the byte after this instruction
  1350.  
  1351.           5. ===> Advanced version only:
  1352.              An expression that evaluates out to type address.
  1353.              Example:
  1354.  
  1355.                     MOV AX, buffer+3
  1356.              BUFFER DS 20
  1357.  
  1358.              See the "Operand Expressions" section for more details.
  1359.  
  1360.  
  1361.  
  1362.  
  1363.  
  1364.  
  1365.  
  1366.  
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.  
  1379.  
  1380.  
  1381.                                                                    20
  1382.  
  1383.        B. Indirect Memory Address:  The address of the operand is the
  1384.           sum of the contents of the indicated register(s) and a
  1385.           displacement.  The register, or sum of registers, are
  1386.           enclosed in square brackets: []
  1387.  
  1388.           The displacement is optional, and takes the form of an
  1389.           immediate operand, placed without intervening delimiters to
  1390.           the left of the first bracket.
  1391.  
  1392.           Immediate data written as decimal numbers, with values
  1393.           between 127 and -128 generate a signed 8 bit offset.
  1394.           Values outside this range, or those expressed in some
  1395.           other manner generate 16 bit offsets.
  1396.  
  1397.           The following indirect modes are provided:
  1398.  
  1399.           1. Indirect through a base register (BX or BP).  Examples:
  1400.  
  1401.              ENTRYLENGTH EQU 6
  1402.                          MOV AX, ENTRYLENGTH[BP]
  1403.                          MOV DL, -2[BX]
  1404.                          MOV CX, TURBO(COUNT)[BP]
  1405.                          MOV 9A9AH[BX], AX
  1406.  
  1407.           2. Indirect through an index register (DI or SI).
  1408.              Examples:
  1409.  
  1410.              MOV [DI], CX
  1411.              MOV CX, -5[SI]
  1412.  
  1413.           3. Indirect through the sum of one base register and one
  1414.              index register.  Examples:
  1415.  
  1416.              MOV [BP+DI], SP      ;note that no spaces are
  1417.              MOV BX, 10H[BX+SI]   ;allowed within the
  1418.              MOV CL, [BP+SI]      ;brackets.
  1419.              MOV DH, -2[BX+DI]
  1420.  
  1421.  
  1422.  
  1423.  
  1424.  
  1425.  
  1426.  
  1427.  
  1428.  
  1429.  
  1430.  
  1431.  
  1432.  
  1433.  
  1434.  
  1435.  
  1436.  
  1437.  
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.                                                                    21
  1448.  
  1449.     4. Labels
  1450.  
  1451.        A label on most instructions may be used as an operand for
  1452.        call and jump instructions.  See the section titled "Labels"
  1453.        for more information.  Examples:
  1454.  
  1455.        START    PROC NEAR
  1456.                 CALL GETINPUT
  1457.                 JMPS START
  1458.                 ENDP
  1459.        GETINPUT PROC NEAR
  1460.  
  1461.     5. Strings
  1462.  
  1463.        A string is any sequence of characters (including delimiters)
  1464.        surrounded by single quotes (').  If you want to use the
  1465.        single quote character inside a string, put two of them
  1466.        in a row for each one you want in the string. Example:
  1467.  
  1468.        DB 'This is a ''string'' with embedded quotes'
  1469.  
  1470.  
  1471.  
  1472.  
  1473.  
  1474.  
  1475.  
  1476.  
  1477.  
  1478.  
  1479.  
  1480.  
  1481.  
  1482.  
  1483.  
  1484.  
  1485.  
  1486.  
  1487.  
  1488.  
  1489.  
  1490.  
  1491.  
  1492.  
  1493.  
  1494.  
  1495.  
  1496.  
  1497.  
  1498.  
  1499.  
  1500.  
  1501.  
  1502.  
  1503.  
  1504.  
  1505.  
  1506.  
  1507.  
  1508.  
  1509.  
  1510.  
  1511.  
  1512.  
  1513.                                                                    22
  1514.  
  1515.     >>Operand Expressions<<
  1516.  
  1517.     CHASM can perform arithmetic calculations at assemble time, to
  1518.     help you generate memory addresses and immediate data constants.
  1519.  
  1520.     The following operand types can participate in operand
  1521.     expressions: 
  1522.  
  1523.          immediate data
  1524.          program locations
  1525.          data storage locations
  1526.  
  1527.     Actually, for the purpose of expression evaluation, CHASM treats
  1528.     both program locations and data storage locations identically.
  1529.     Thus, really only two types of operands are allowed in
  1530.     expressions: immediate and address.
  1531.  
  1532.     Symbols standing for immediate operands must have been defined
  1533.     prior to use in an expression, or you may get Phase Errors (see
  1534.     the error message section for a discussion on this topic).  You
  1535.     should put all your EQU and STRUC pseudo-ops at the beginning of
  1536.     your program, before any machine instructions.
  1537.  
  1538.     The following arithmetic operators are available:
  1539.  
  1540.          +  addition
  1541.          -  subtraction
  1542.          *  multiplication
  1543.          /  integer division
  1544.  
  1545.     Note that / performs *integer* division.  5/2 evaluates to 2.
  1546.  
  1547.     The normal rules of precedence apply.  To force evaluation
  1548.     contrary to normal precedence, you can use parenthesis: ().
  1549.  
  1550.          MOV AX  2+5*3   ;means mov ax, 17 because * outranks +
  1551.          MOV AX, (2+5)*3 ;means mov ax, 21
  1552.  
  1553.     No delimiters can appear within an expression.  If you separate
  1554.     the parts of an expression with delimiters, CHASM will try to
  1555.     interpret each part as a separate operand.
  1556.  
  1557.          MOV [BX], BUFFER + 3    ;WRONG!!
  1558.          MOV [BX], BUFFER+3      ;ok
  1559.  
  1560.  
  1561.  
  1562.  
  1563.  
  1564.  
  1565.  
  1566.  
  1567.  
  1568.  
  1569.  
  1570.  
  1571.  
  1572.  
  1573.  
  1574.  
  1575.  
  1576.  
  1577.  
  1578.  
  1579.                                                                    23
  1580.  
  1581.     The type of an operand expression is determined by the individual
  1582.     operand types that are combined within it.  In evaluating each
  1583.     operation in an expression, the result type follows this rule:
  1584.  
  1585.          If the two operand types are the same, the result type is
  1586.          IMMEDIATE.
  1587.  
  1588.          If the two operand types are different, the result type is
  1589.          an ADDRESS.
  1590.  
  1591.     In expressions, both program locations and data storage locations
  1592.     are considered identical.  An expression which evaluates to type
  1593.     address can be used in either a MOV or a JMP.
  1594.  
  1595.     The result type of a complicated expression is determined by
  1596.     replacing individual binary operations with their result, and
  1597.     evaluating the (simpler) expression thus formed, following the
  1598.     above rules.
  1599.  
  1600.     Here's a program fragment with some expressions, and a discussion
  1601.     of their types and significance:
  1602.  
  1603.     EXPSAMPLE PROC  NEAR
  1604.               MOV   AX, 3+5         ;immediate, calculated value
  1605.               MOV   DX, STRING-END  ;immediate, length of string
  1606.               MOV   STRING+5, 'A'   ;address, fifth byte of string
  1607.               JMP   EXPSAMPLE+100H  ;address, used as program loc.
  1608.               JMP   STRING+100H     ;valid address syntax, but silly
  1609.     STRING    DB    'MESSaGE'       ;data area
  1610.     END                             ;marks position of end of string
  1611.  
  1612.  
  1613.     The special symbol '$' returns the current value of CHASM's
  1614.     location counter for use in expressions.  $ is of type address.
  1615.     Thus, $-1 is the address of the byte immediately prior to the
  1616.     instruction currently being assembled.
  1617.  
  1618.  
  1619.  
  1620.  
  1621.  
  1622.  
  1623.  
  1624.  
  1625.  
  1626.  
  1627.  
  1628.  
  1629.  
  1630.  
  1631.  
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.                                                                    24
  1646.  
  1647.     The rules for typing expressions were set up to produce the
  1648.     "most useful" result type, taking a guess as to why one would
  1649.     want to do a given calculation.  If the type isn't what you have
  1650.     in mind, you can coerce CHASM using square brackets or the
  1651.     OFFSET function:
  1652.  
  1653.           MOV AX, 3+5              ;immediate
  1654.           MOV AX, [3+5]            ;coerced to address
  1655.           MOV DX, $+4              ;address
  1656.           MOV DX, OFFSET($+4)      ;coerced to immediate
  1657.  
  1658.     Under certain circumstances, CHASM can get confused when you use
  1659.     OFFSET or LENGTH functions in expressions.  The problem occurs if
  1660.     the expression starts with a function, and ends with a close
  1661.     parenthesis:
  1662.  
  1663.           MOV AX, OFFSET(BUFFER)*(3+2)    ;will be misinterpreted
  1664.  
  1665.     CHASM will try to interpret this as the offset of "BUFFER)*(3+2",
  1666.     and you'll get the error message "Illegal or undefined argument
  1667.     for OFFSET".  The solution is to enclose the whole works in
  1668.     parenthesis, to force CHASM to recognize it as an expression:
  1669.  
  1670.           MOV AX, (OFFSET(BUFFER)*(3+2))  ;correct
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.  
  1680.  
  1681.  
  1682.  
  1683.  
  1684.  
  1685.  
  1686.  
  1687.  
  1688.  
  1689.  
  1690.  
  1691.  
  1692.  
  1693.  
  1694.  
  1695.  
  1696.  
  1697.  
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711.                                                                    25
  1712.  
  1713.     >>Resolution of Ambiguities<<
  1714.  
  1715.     The language defined in "The 8086 Book" contains a number of
  1716.     ambiguities which must be resolved by an assembler.  This is
  1717.     discussed throughout the book, but pages 3-285 and 3-286
  1718.     specifically cover this topic.  CHASM's solutions of these
  1719.     problems are discussed in this section.
  1720.  
  1721.     A. 8088 Memory references:
  1722.  
  1723.     When one specifies the address of a memory location, it is
  1724.     unclear how large an operand is being referenced.  An operand
  1725.     might be a byte, or a word.
  1726.  
  1727.        1. If a register is present as an operand, it is assumed that
  1728.           the memory operand matches the register in size.  An
  1729.           exception to this rule are the shift and rotate
  1730.           instructions, where the CL register is used as a counter,
  1731.           and has nothing to do with the size of the other operand.
  1732.           Examples:
  1733.  
  1734.           MOV MASK, AX  ;mask is a word
  1735.           MOV DH, [BX]  ;BX points to a byte
  1736.           NEG [SI]      ;error, operand of unknown size
  1737.           SHR FLAG, CL  ;error, flag is of unknown size
  1738.  
  1739.        2. If no register is present, (or if the only register is CL
  1740.           being used as a counter) the size of the memory operand is
  1741.           specified by adding the suffix "B" or "W" to the
  1742.           instruction mnemonic.  Examples:
  1743.  
  1744.           NEGB [SI]        ;SI points to a byte
  1745.           SHRW FLAG, CL    ;flag is a word
  1746.           MOVW MASK, 0AH   ;mask is a word
  1747.           MOVB MASK, 0AH   ;mask is a byte
  1748.           MOVW MASK, 9A9AH ;must specify size even though
  1749.                            ;immediate operand implies word
  1750.  
  1751.  
  1752.  
  1753.  
  1754.  
  1755.  
  1756.  
  1757.  
  1758.  
  1759.  
  1760.  
  1761.  
  1762.  
  1763.  
  1764.  
  1765.  
  1766.  
  1767.  
  1768.  
  1769.  
  1770.  
  1771.  
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.                                                                    26
  1778.  
  1779.     B. 8087 Memory References:
  1780.  
  1781.        All real and integer 8087 memory references are ambiguous as
  1782.        to the operand size.  Integer operands could be word, short,
  1783.        or long.  Reals can be short, long or temporary real.  As with
  1784.        8088 memory references, you specify the size using a suffix:
  1785.  
  1786.              W: word
  1787.              S: short
  1788.              L: long
  1789.              T: temporary real
  1790.  
  1791.        For more details and examples, see the section on 8087
  1792.        support.
  1793.  
  1794.     C. Indirect Branching.
  1795.  
  1796.     The 8088 supports two flavors of indirect branching: intra, and
  1797.     intersegment.  A register is set to point at a memory location
  1798.     which contains a new value for the program counter, and in the
  1799.     case of intersegment branching, a new value for the CS register
  1800.     as well.
  1801.  
  1802.     The syntax of "The 8086 Book" does not specify which flavor of
  1803.     branch is being invoked.  CHASM adds the suffixes "N" (for near,
  1804.     or intrasegment) and "F" (for far, or intersegment) to the
  1805.     indirect CALL and JMP mnemonics.  Examples:
  1806.  
  1807.        CALLN [BX]    ;intrasegment call
  1808.        JMPF  [DI]    ;intersegment jump
  1809.        JMP   [BP]    ;error, unspecified flavor
  1810.  
  1811.     D. Long and Short Jumps
  1812.  
  1813.     Two types of relative jumps are supported by the 8088: short
  1814.     (specified by a signed 8 bit displacement) and long (specified by
  1815.     a 16 bit displacement).  Both are implemented in CHASM as a jump
  1816.     to a label.
  1817.  
  1818.     The short jump is specified by mnemonic JMPS. Since one of the
  1819.     displacement bits is used to indicate direction, only seven are
  1820.     left to express the magnitude of jump.  JMPS (and similarly, all
  1821.     the jump on condition instructions) is thus limited to branching
  1822.     to labels within a range of -128 to +127 bytes.
  1823.  
  1824.  
  1825.  
  1826.  
  1827.  
  1828.  
  1829.  
  1830.  
  1831.  
  1832.  
  1833.  
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.  
  1842.  
  1843.                                                                    27
  1844.  
  1845.     CHASM reserves mnemonic JMP for the long jump.  JMP may be used
  1846.     to jump anywhere within the program segment, but the object code
  1847.     generated is less compact than that from JMPS.
  1848.  
  1849.     Examples:
  1850.  
  1851.        START PROC NEAR
  1852.              JMPS END     ;short jump
  1853.              JMP  START   ;long jump
  1854.        END   ENDP
  1855.  
  1856.  
  1857.     E. Instruction Prefixes.
  1858.  
  1859.     The 8088 supports three instruction prefixes:
  1860.  
  1861.        1. SEG: segment override. An alternate segment register is
  1862.           specified for a reference to memory.
  1863.  
  1864.        2. REP, REPE,REPNE,REPZ,REPNZ: repeat. A string primitive is
  1865.           repeated until a condition is met.
  1866.  
  1867.        3. LOCK: Turns on the LOCK signal. Only useful in
  1868.           multi-processor situations.
  1869.  
  1870.     SEG is implemented as a modifier attached to a memory operand.
  1871.     If you want to override the default segment register for a memory
  1872.     access, precede the memory operand with the segment register
  1873.     followed by a colon.  Examples:
  1874.  
  1875.        MOV AX, ES:FLAG     ;flag is in the extra segment
  1876.        MOV CS:[100H], DX   ;offset 100H in the code segment
  1877.  
  1878.  
  1879.  
  1880.  
  1881.  
  1882.  
  1883.  
  1884.  
  1885.  
  1886.  
  1887.  
  1888.  
  1889.  
  1890.  
  1891.  
  1892.  
  1893.  
  1894.  
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.                                                                    28
  1910.  
  1911.     The other prefixes are implemented as separate instructions. They
  1912.     appear on a separate line, immediately before the instruction
  1913.     which they modify.  For compatibility with earlier versions of
  1914.     CHASM, you can also specify segment overrides on a separate line,
  1915.     using the mnemonic SEG. Examples:
  1916.  
  1917.        REP
  1918.        MOVSB           ;move bytes until CX decremented to 0
  1919.        SEG SS
  1920.        MOV AX,BUFFER   ;buffer is in the stack segment
  1921.        LOCK
  1922.        MOV [8FFH], AX  ;lock bus to ensure data is transferred
  1923.                        ;before other processors try to access it
  1924.  
  1925.     Note for 8087 users:  You may get unexpected results using the
  1926.        separate instruction form of SEG on 8087 instructions.  Use
  1927.        the operand modifier form for segment overrides on 8087
  1928.        instructions.
  1929.  
  1930.  
  1931.  
  1932.  
  1933.  
  1934.  
  1935.  
  1936.  
  1937.  
  1938.  
  1939.  
  1940.  
  1941.  
  1942.  
  1943.  
  1944.  
  1945.  
  1946.  
  1947.  
  1948.  
  1949.  
  1950.  
  1951.  
  1952.  
  1953.  
  1954.  
  1955.  
  1956.  
  1957.  
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.                                                                    29
  1976.  
  1977.     >>Pseudo-Operations<<
  1978.  
  1979.     The following pseudo-ops are implemented:
  1980.  
  1981.     A. BSAVE: Generate object code in BSAVE format.
  1982.  
  1983.        Instructs CHASM to build a header in the format of BASIC's
  1984.        BSAVE command.  The resulting object code file may be BLOADed
  1985.        by BASIC programs.  No operands are required, and the
  1986.        pseudo-op may appear anywhere within the source code.
  1987.        Example: 
  1988.  
  1989.              ORG    0     ;no psp
  1990.        SUBRT PROC   FAR   ;subroutine for BASIC program
  1991.              BSAVE        ;make BLOADable object file
  1992.  
  1993.     B. COUNT ...ENDC:  Count bytes.
  1994.  
  1995.        COUNT was available in earlier versions of CHASM. With the
  1996.        addition of operand expression support, COUNT became obsolete,
  1997.        and was eliminated to make room for new features.
  1998.  
  1999.        Existing programs using COUNT can be modified as in the
  2000.        following example.  The length of the string is calculated by
  2001.        subtracting two labels, one just before the string, one just
  2002.        after it:
  2003.  
  2004.        MESSAGE    COUNT
  2005.        MSG_TXT    DB   'This utility requires DOS 2.0!' beep cr lf
  2006.                   ENDC
  2007.                   MOV CX, LENGTH(MESSAGE)
  2008.  
  2009.        becomes:
  2010.  
  2011.        MSG_TXT    DB   'This utility requires DOS 2.0!' beep cr lf
  2012.        MSG_END
  2013.                   MOV   CX, MSG_END-MSG_TXT
  2014.  
  2015.  
  2016.  
  2017.  
  2018.  
  2019.  
  2020.  
  2021.  
  2022.  
  2023.  
  2024.  
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.                                                                    30
  2042.  
  2043.     C. DB: Declare Bytes
  2044.  
  2045.        Memory locations are filled with values from the operand list.
  2046.        Any number of operands may appear, but all must fit on one
  2047.        line. Acceptable operands are immediate data, or strings
  2048.        enclosed in single quotes (').  DB interprets strings as a
  2049.        series of ASCII bytes.
  2050.  
  2051.        If a label appears, it is redefined as a memory location, and
  2052.        the data area may be referred to using the label, rather than
  2053.        an address. Examples:
  2054.  
  2055.              MOV AX,MASK
  2056.        MASK  DB  00H,01H
  2057.        STG   DB  'A string operand'
  2058.  
  2059.        CHASM generates an error message ("Data too large") if word
  2060.        operands (such as OFFSETs, or numbers greater than 255) are
  2061.        found in the DB operand list. DW should be used for declaring
  2062.        words.
  2063.  
  2064.     D. DM: Declare Multiple Bytes
  2065.  
  2066.        Like COUNT, DM became obsolete when operand expressions became
  2067.        available, and has been eliminated to make room for new
  2068.        features.  Existing programs using DM can be modified as
  2069.        follows:
  2070.  
  2071.            DM  500, ENTRYLENGTH
  2072.  
  2073.        becomes:
  2074.  
  2075.            DS  500*ENTRYLENGTH
  2076.  
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.  
  2085.  
  2086.  
  2087.  
  2088.  
  2089.  
  2090.  
  2091.  
  2092.  
  2093.  
  2094.  
  2095.  
  2096.  
  2097.  
  2098.  
  2099.  
  2100.  
  2101.  
  2102.  
  2103.  
  2104.  
  2105.  
  2106.  
  2107.                                                                    31
  2108.  
  2109.     E. DS: Declare Storage
  2110.  
  2111.        Used to declare large blocks of identically initialized
  2112.        storage.  The first operand is required, a number specifying
  2113.        how many bytes are declared.  If a second operand in the form
  2114.        of a number 0-FFH appears, the locations will all be
  2115.        initialized to this value.  If the second operand is not
  2116.        present, locations are initialized to 0.   As with DB, any
  2117.        label is redefined as a memory location.  To save space, the
  2118.        object code does not appear on the listing.  Examples:
  2119.  
  2120.           DS 10         ;10 locs initialized to 0
  2121.           DS 100H,1AH   ;256 locs initialized to 1AH
  2122.  
  2123.     F. DW: Declare Words
  2124.  
  2125.        Used to unambiguously assign a word of storage for each item
  2126.        in the operand list.  Any number of immediate operands may
  2127.        appear, but all must fit on one line.  As with DB, any label
  2128.        is redefined as a memory location. Example:
  2129.  
  2130.            DW 0012H, FFFFH       ;four bytes declared
  2131.  
  2132.     G. EJECT: Begin New Print Page
  2133.  
  2134.        When listing is enabled, causes CHASM to move to the top of
  2135.        the next listing page.  Normally has no effect on listings
  2136.        sent to the screen or to disk, although you can enable EJECTs
  2137.        in disk listings with CHASM's /DPAGE configuration switch.
  2138.  
  2139.     H. EJECTIF: Conditional Page Break
  2140.  
  2141.        Requires one immediate operand.  If listing is enabled
  2142.        and fewer than that many lines are left on the current page of
  2143.        the listing, CHASM will move to the top of the next page.
  2144.  
  2145.        If you put an appropriate EJECTIF at the beginning of each
  2146.        procedure or section of your programs, CHASM will keep them in
  2147.        one piece.  Like EJECT, EJECTIF normally has no effect on
  2148.        listings to the screen or disk.  You can enable EJECTIF for
  2149.        disk listings with CHASM's /DPAGE configuration switch.
  2150.        Example:
  2151.  
  2152.            EJECTIF 20    ;following procedure is 20 lines long
  2153.  
  2154.  
  2155.  
  2156.  
  2157.  
  2158.  
  2159.  
  2160.  
  2161.  
  2162.  
  2163.  
  2164.  
  2165.  
  2166.  
  2167.  
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173.                                                                    32
  2174.  
  2175.     I. ENDP: End of Procedure
  2176.  
  2177.        See PROC (below) for details.
  2178.  
  2179.     J. ENDSTRUC: End of Structure
  2180.  
  2181.        ==>Advanced version only.  See STRUC (below) for details.
  2182.  
  2183.     K. EQU: Equate
  2184.  
  2185.        Used to equate a symbolic name with a number. The symbol may
  2186.        then be used anywhere the number would be used.  Use of
  2187.        symbols makes programs more understandable, and simplifies
  2188.        modification.
  2189.  
  2190.        An alternate form of EQU encloses the number in square
  2191.        brackets: []. The symbol is then interpreted as a memory
  2192.        location, and may be used as an address for memory access.
  2193.        This version is provided to allow symbolic reference to
  2194.        locations outside the program segment. Examples:
  2195.  
  2196.           MOFFSET    EQU 0B000H
  2197.           MONOCHROME EQU [0000H]
  2198.  
  2199.        Warning: Difficult to debug errors may result from using a
  2200.        ======>  symbol prior to its being defined by EQU.  You are
  2201.                 strongly urged to group all your equates together at
  2202.                 the beginning of programs, before any other
  2203.                 instructions. See "Phase Error" in the Error Message
  2204.                 section.
  2205.  
  2206.     L. INLINE: Generate Turbo Pascal inline statements
  2207.  
  2208.        Instructs CHASM to output object code in the form of a text
  2209.        file, suitable for including in Turbo Pascal inline
  2210.        statements.  The resulting object file is not directly
  2211.        executable, but with minimal editing, can be compiled by Turbo
  2212.        Pascal as inline data.
  2213.  
  2214.        INLINE can appear anywhere in your source file, and requires
  2215.        no operands.
  2216.  
  2217.        See the "Execution of Assembled Programs" section of this
  2218.        document for examples, and more details.
  2219.  
  2220.  
  2221.  
  2222.  
  2223.  
  2224.  
  2225.  
  2226.  
  2227.  
  2228.  
  2229.  
  2230.  
  2231.  
  2232.  
  2233.  
  2234.  
  2235.  
  2236.  
  2237.  
  2238.  
  2239.                                                                    33
  2240.  
  2241.     M. IFXX... [ELSE]... ENDIF: Conditional Assembly
  2242.  
  2243.        ===> Advanced version only.
  2244.  
  2245.        CHASM's conditional assembly pseudo-ops can be used to cause
  2246.        macros to expand differently according to the parameters
  2247.        supplied on the invocation.  Many different IF pseudo-ops are
  2248.        provided, to allow testing for (in)equality, relative size,
  2249.        and (non)existence of parameters.  You can also test whether a
  2250.        parameter is a register, and if so, what type.
  2251.  
  2252.        For more details and examples, see the Macro section of this
  2253.        document.
  2254.  
  2255.     N. INCLUDE: Include file
  2256.  
  2257.        ==>Advanced version only.
  2258.  
  2259.        INCLUDE requires one string operand, a filename enclosed in
  2260.        single quotes.  If desired, you can specify a drive and/or a
  2261.        path as part of the filename.
  2262.  
  2263.        The contents of the specified file are logically inserted into
  2264.        the source file at the point where the INCLUDE appears.
  2265.        INCLUDEs cannot be nested: an error message will be printed if
  2266.        the specified file itself contains an INCLUDE.  Example:
  2267.  
  2268.            INCLUDE '\ASM\STDIO.HDR'    ;bring in standard library
  2269.  
  2270.     O. LIST: Enable listing output
  2271.  
  2272.        Output to the list device is enabled, presumably after a
  2273.        NOLIST was encountered.  No operands required.
  2274.  
  2275.  
  2276.  
  2277.  
  2278.  
  2279.  
  2280.  
  2281.  
  2282.  
  2283.  
  2284.  
  2285.  
  2286.  
  2287.  
  2288.  
  2289.  
  2290.  
  2291.  
  2292.  
  2293.  
  2294.  
  2295.  
  2296.  
  2297.  
  2298.  
  2299.  
  2300.  
  2301.  
  2302.  
  2303.  
  2304.  
  2305.                                                                    34
  2306.  
  2307.     P. MACRO ...ENDM: Macro Definition
  2308.  
  2309.        ==> Advanced version only.
  2310.  
  2311.        Declares a macro.  MACRO requires no operands, and signals
  2312.        CHASM that the following lines constitute a macro definition,
  2313.        and are to be stored for later use, rather than assembled in
  2314.        place.  A label is required on the MACRO statement to name the
  2315.        defined macro.
  2316.  
  2317.        ENDM terminates the macro definition, and requires no
  2318.        operands.
  2319.  
  2320.        For more information and examples, see the section titled
  2321.        "Macros".
  2322.  
  2323.     Q. NOLIST: Disable listing output
  2324.  
  2325.        Normal output to the list device is disabled.  Error messages
  2326.        are listed as usual.  No operands required.
  2327.  
  2328.     R. ORG: Origin
  2329.  
  2330.        Allows direct manipulation of the location counter during
  2331.        assembly.  By default, CHASM assembles code to start at offset
  2332.        100H, thus leaving room for the program segment prefix
  2333.        normally built by COMMAND or DEBUG.  In situations where no
  2334.        PSP is provided, such as routines to be called from BASIC, you
  2335.        should override this default with ORG, or incorrect assembly
  2336.        may result.
  2337.  
  2338.        ORG requires one operand, a number between 0 and FFFFH, which
  2339.        represents the new setting of CHASM's location counter.
  2340.        Although the location counter may be reset anywhere within a
  2341.        program, generally this pseudo-op should be used before any
  2342.        machine executable instructions for meaningful results.
  2343.  
  2344.        Example:
  2345.  
  2346.          ORG 0   ;Code will be assembled for starting
  2347.                  ;offset of 0
  2348.  
  2349.  
  2350.  
  2351.  
  2352.  
  2353.  
  2354.  
  2355.  
  2356.  
  2357.  
  2358.  
  2359.  
  2360.  
  2361.  
  2362.  
  2363.  
  2364.  
  2365.  
  2366.  
  2367.  
  2368.  
  2369.  
  2370.  
  2371.                                                                    35
  2372.  
  2373.     S. PROC ...ENDP: Procedure Definition
  2374.  
  2375.        Declares a procedure.  One operand is required on PROC, either
  2376.        the word NEAR, or the word FAR.  This pseudo-op warns CHASM
  2377.        whether to assemble returns as intra (near) or intersegment
  2378.        (far).  Procedures called from within the program being
  2379.        assembled should be declared NEAR.  Generally, all others
  2380.        should be FAR.  ENDP terminates the procedure, and requires no
  2381.        operands.  If a RET is encountered outside of a declared
  2382.        procedure, an error occurs.  Procedures may be nested, up to
  2383.        10 deep.  Example:
  2384.  
  2385.        MAIN  PROC  FAR
  2386.              ...
  2387.              ...      ;body of procedure
  2388.              ENDP
  2389.  
  2390.     T. RADIX:  Default Number Base
  2391.  
  2392.        CHASM's default radix is 10, meaning that numbers are assumed
  2393.        to be in base 10 unless they end in "B" or "H".  The RADIX
  2394.        pseudo-op allows you to change this default.  Allowed RADIX
  2395.        values are 16 and 10.  Setting RADIX 16 allows you to specify
  2396.        hex numbers without the trailing "H".
  2397.  
  2398.        Note that when RADIX 16 is in effect, there is no way to
  2399.        specify numbers in base 1 (binary) or base 10 (decimal).  To
  2400.        write in either of these bases, shift back to RADIX 10.  For
  2401.        example:
  2402.  
  2403.           RADIX 16
  2404.           mov   ax, 1B     ;means 1B in hexadecimal
  2405.           mov   ax, 20     ;means 20 in hexadecimal
  2406.           mov   ax, 30H    ;trailing "H" allowed, but not necessary
  2407.           RADIX 10
  2408.           mov   ax, 1B     ;means 1 in binary
  2409.           mov   ax, 20     ;means 20 in decimal
  2410.           mov   ax, 30H    ;means 30 in hexadecimal
  2411.  
  2412.  
  2413.  
  2414.  
  2415.  
  2416.  
  2417.  
  2418.  
  2419.  
  2420.  
  2421.  
  2422.  
  2423.  
  2424.  
  2425.  
  2426.  
  2427.  
  2428.  
  2429.  
  2430.  
  2431.  
  2432.  
  2433.  
  2434.  
  2435.  
  2436.  
  2437.                                                                    36
  2438.  
  2439.     U. STRUC ...ENDSTRUC: Structure Definition
  2440.  
  2441.        ==> Advanced version only.
  2442.  
  2443.        Declares a structure.  STRUC requires no operands, and signals
  2444.        CHASM that the following lines constitute a structure
  2445.        template, and not actual storage declaration.  If a label
  2446.        appears on the STRUC, the label is equated with the length of
  2447.        the structure.
  2448.  
  2449.        ENDSTRUC terminates the structure definition, and requires no
  2450.        operands.
  2451.  
  2452.        Inside the structure, storage defining pseudo-ops behave
  2453.        somewhat differently.  See the section titled "Structures" for
  2454.        more information. Example:
  2455.  
  2456.            DIRENTRY STRUC      ;disk directory entry
  2457.            NAME     DS    8
  2458.            EXT      DS    3
  2459.            ATRIB    DS    1
  2460.            RESERVED DS   10
  2461.            TIME     DS    2
  2462.            DATE     DS    2
  2463.            START    DS    2
  2464.            SIZE     DS    4
  2465.                     ENDSTRUC
  2466.  
  2467.  
  2468.     V. WAITON / WAITOFF: Toggle Automatic WAIT Assembly
  2469.  
  2470.        CHASM normally assembles WAIT instructions before most 8087
  2471.        instructions.  After a WAITOFF pseudo-op is encountered, CHASM
  2472.        will not add WAITs.  This allows you to let the 8088 and 8087
  2473.        run in parallel for greater speed, putting in WAITs manually
  2474.        where synchronization is important.  WAITON turns automatic
  2475.        WAIT assembly back on.
  2476.  
  2477.     W. CHKJMP / NOCHKJMP
  2478.  
  2479.        Following a CHKJMP pseudo-op, CHASM will check each JMP
  2480.        instruction to see if it could have been coded as JMPS (to
  2481.        produce tighter code).  JMP instructions with displacements
  2482.        smaller than 128 bytes will be flagged with a diagnostic
  2483.        message ("Could Use JMPS").  NOCHKJMP turns off JMP checking.
  2484.  
  2485.  
  2486.  
  2487.  
  2488.  
  2489.  
  2490.  
  2491.  
  2492.  
  2493.  
  2494.  
  2495.  
  2496.  
  2497.  
  2498.  
  2499.  
  2500.  
  2501.  
  2502.  
  2503.                                                                    37
  2504.  
  2505.  
  2506.     X. = : Assignment to Assembler Variable
  2507.  
  2508.        CHASM supports the use of "assembler variables", which can be
  2509.        dynamically redefined throughout your program.  The assignment
  2510.        operator "=" acts similarly to pseudo-op EQU.  A label on a
  2511.        "=" line will be defined as equivalent to the operand, until
  2512.        it is redefined by another assignment statement.  Unlike EQU,
  2513.        with "=" you can assign any valid operand type (except string)
  2514.        to the assembler variable. These assignments do *NOT* result
  2515.        in object code generation - they simply redefine a symbol to
  2516.        have different meanings to CHASM in different parts of your
  2517.        program.  For example:
  2518.  
  2519.        x    =   [80]
  2520.             mov ax, x      ;means mov ax, [80]
  2521.        x    =   bx
  2522.             mov ax, x      ;x  redefined, means mov ax, bx
  2523.        x    =   100H
  2524.             mov ax, x      ;redefined again, means mov ax, 100H
  2525.  
  2526.  
  2527.  
  2528.  
  2529.  
  2530.  
  2531.  
  2532.  
  2533.  
  2534.  
  2535.  
  2536.  
  2537.  
  2538.  
  2539.  
  2540.  
  2541.  
  2542.  
  2543.  
  2544.  
  2545.  
  2546.  
  2547.  
  2548.  
  2549.  
  2550.  
  2551.  
  2552.  
  2553.  
  2554.  
  2555.  
  2556.  
  2557.  
  2558.  
  2559.  
  2560.  
  2561.  
  2562.  
  2563.  
  2564.  
  2565.  
  2566.  
  2567.  
  2568.  
  2569.                                                                    38
  2570.  
  2571.     >>Macros<<
  2572.  
  2573.     ==>Advanced version only.
  2574.  
  2575.     Macros are an advanced feature.  Beginners may wish to skip this
  2576.     section until they become more experienced with CHASM and
  2577.     assembly language programming.
  2578.  
  2579.     A. Introduction
  2580.  
  2581.        Macros are a shorthand way of writing frequently used
  2582.        sections of code.  Using macros, you can write a code fragment
  2583.        once, then any time you want to use it, just reference it by
  2584.        name.  Once you define a macro and give it a name, anywhere
  2585.        CHASM sees the name will be automatically "expanded" into the
  2586.        previously defined code.
  2587.  
  2588.        For example, suppose you were writing a large program, and at
  2589.        the beginning of each subroutine you pushed all the general
  2590.        purpose registers onto the stack to save their contents.
  2591.        Every subroutine would start out something like this:
  2592.  
  2593.              push ax       ;save register contents
  2594.              push bx
  2595.              push cx
  2596.              push dx
  2597.  
  2598.        Before long, you'd get pretty sick of writing the same thing
  2599.        for each subroutine.  Macros are a way to put some of the
  2600.        boring, repetitive nature of assembly language into the hands
  2601.        of the assembler, freeing you up for the more creative
  2602.        aspects.  Here's how you define a CHASM macro to take the
  2603.        place of this code fragment:
  2604.  
  2605.        savestate  macro
  2606.                   push ax           ;save general purpose registers
  2607.                   push bx
  2608.                   push cx
  2609.                   push dx
  2610.                   endm
  2611.  
  2612.  
  2613.  
  2614.  
  2615.  
  2616.  
  2617.  
  2618.  
  2619.  
  2620.  
  2621.  
  2622.  
  2623.  
  2624.  
  2625.  
  2626.  
  2627.  
  2628.  
  2629.  
  2630.  
  2631.  
  2632.  
  2633.  
  2634.  
  2635.                                                                    39
  2636.  
  2637.        Note the MACRO and ENDM statements.  These signal to CHASM
  2638.        that the enclosed code is a macro definition to be saved for
  2639.        later use, rather than code to be assembled at this point in
  2640.        your program.  The MACRO statement also gives a name
  2641.        (SAVESTATE) to the macro, which will take the place of the
  2642.        stored code.
  2643.  
  2644.        Now, at the beginning of each subroutine you can just write
  2645.        "SAVESTATE" when you want to push the general purpose
  2646.        registers. Here's an example:
  2647.  
  2648.        get_input  proc  near
  2649.                   savestate
  2650.                   ...
  2651.                   ...
  2652.                   endp
  2653.  
  2654.        Given the previous macro definition, the above example is
  2655.        *exactly* equivalent to:
  2656.  
  2657.        get_input  proc  near
  2658.                   push ax
  2659.                   push bx
  2660.                   push cx
  2661.                   push dx
  2662.                   ...
  2663.                   ...
  2664.                   endp
  2665.  
  2666.        The only difference is that less busy work is required on your
  2667.        part.
  2668.  
  2669.        Macros are NOT subroutines!  Subroutines are coded once, then
  2670.        called within your program at run time.  Macros are expanded
  2671.        in-line at assembly time, and the code is inserted into your
  2672.        program at the invocation point.  If you invoke the macro 20
  2673.        times in your program, you'll end up with 20 copies of the
  2674.        macro code. 
  2675.  
  2676.  
  2677.  
  2678.  
  2679.  
  2680.  
  2681.  
  2682.  
  2683.  
  2684.  
  2685.  
  2686.  
  2687.  
  2688.  
  2689.  
  2690.  
  2691.  
  2692.  
  2693.  
  2694.  
  2695.  
  2696.  
  2697.  
  2698.  
  2699.  
  2700.  
  2701.                                                                    40
  2702.  
  2703.        Although this does waste some memory space, you save execution
  2704.        time by eliminating the subroutine call and return process.
  2705.        At a minimum, it takes 32 machine cycles to call a subroutine.
  2706.        The four instruction macro given above requires 40 cycles to
  2707.        execute.  If it were coded as a subroutine, the time to
  2708.        execute it would almost *double*.  Macros trade off space for
  2709.        speed.
  2710.  
  2711.     B. Macro Parameters
  2712.  
  2713.        CHASM's macros allow 9 user defined parameters, which are
  2714.        evaluated at expansion time.  The parameters work just like
  2715.        those in DOS batch files.  Here's an example of a macro with
  2716.        one parameter.  PRINT calls DOS function 9 to print a string
  2717.        on the console.  A parameter is used to specify the name of
  2718.        the string to be printed:
  2719.  
  2720.        print    macro
  2721.                 mov  ah, 09H          ;specify print string function
  2722.                 mov  dx, offset(%1)   ;point to string
  2723.                 int  21H              ;call DOS
  2724.                 endm
  2725.  
  2726.        Given this definition, when CHASM sees a line like:
  2727.  
  2728.              print title
  2729.  
  2730.        The following code gets inserted in its place:
  2731.  
  2732.              mov  ah, 09H
  2733.              mov  dx, offset(title)
  2734.              int  21H
  2735.  
  2736.        Note how the "%1" in the macro definition got replaced by
  2737.        "title" which was put as an operand on the invocation of the
  2738.        macro.  You can put up to 9 operands onto a macro invocation,
  2739.        and they will be substituted for the dummy parameters %1
  2740.        through %9.
  2741.  
  2742.  
  2743.  
  2744.  
  2745.  
  2746.  
  2747.  
  2748.  
  2749.  
  2750.  
  2751.  
  2752.  
  2753.  
  2754.  
  2755.  
  2756.  
  2757.  
  2758.  
  2759.  
  2760.  
  2761.  
  2762.  
  2763.  
  2764.  
  2765.  
  2766.  
  2767.                                                                    41
  2768.  
  2769.        If you put a label on a macro invocation, two things happen.
  2770.        As usual, the label represents a program location for
  2771.        branching, with offset equal to the beginning of the expanded
  2772.        macro.  You can branch into the expanded macro by using the
  2773.        label as an operand on a jump or call instruction.  In
  2774.        addition, if the special dummy parameter "%0" is used in the
  2775.        macro definition, it is replaced with the label text when the
  2776.        macro is expanded.  This feature is provided to facilitate
  2777.        writing loops within macros.
  2778.  
  2779.        If you fail to provide an operand for any dummy parameter used
  2780.        in the macro definition, CHASM substitutes a null string of
  2781.        length zero.  To leave one parameter blank, but provide
  2782.        replacements for parameters with higher numbers, use the
  2783.        special operand "%B" for the one you want blank.  For example:
  2784.  
  2785.             def_mem  macro
  2786.             %1       db  %2, %3
  2787.                      endm
  2788.  
  2789.                      def_mem twobytes, 128, FFH
  2790.                      def_mem %B, 'Hit any key when ready...'
  2791.  
  2792.        Expands to:
  2793.  
  2794.             twobytes  db 128, FFH
  2795.                       db 'Hit any key when ready...'
  2796.  
  2797.     C. Internal Labels
  2798.  
  2799.        A potential problem exists if you put a label on a statement
  2800.        within a macro.  The first time the macro gets invoked,
  2801.        everything works fine.  However, remember that a given label
  2802.        can only be used once.  The second time you invoke the macro,
  2803.        the line with the label will get a "Duplicate definition"
  2804.        error message.
  2805.  
  2806.        CHASM offers "internal labels" for use within macros.  When
  2807.        expanding macros, CHASM replaces these internal labels with a
  2808.        unique text, different for each invocation of the macro.
  2809.  
  2810.  
  2811.  
  2812.  
  2813.  
  2814.  
  2815.  
  2816.  
  2817.  
  2818.  
  2819.  
  2820.  
  2821.  
  2822.  
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831.  
  2832.  
  2833.                                                                    42
  2834.  
  2835.        Macro internal labels are of the form:
  2836.  
  2837.            %Lx
  2838.  
  2839.        The "%L" signals CHASM that you want an internal label.  The
  2840.        "x" can be any character that isn't a delimiter.  By using
  2841.        different characters, you can define a many different labels
  2842.        in a each macro.
  2843.  
  2844.        Within the macro, you use the internal label symbol just like
  2845.        a normal label.  For example:
  2846.  
  2847.            INTLAB MACRO
  2848.            %LA    MOV AX, DX
  2849.                   JMPS %LA
  2850.                   ENDM
  2851.  
  2852.        Each time this macro is invoked, all occurrences of "%LA" will
  2853.        be replaced with a different text.  (The replacement text will
  2854.        be of the form "%LAnnnn" where "nnnn" is a number.)
  2855.  
  2856.        Using the symbol table dump on your listing, you can figure
  2857.        out what text CHASM used in any given invocation.  DON'T try
  2858.        to use this information to branch into the macro invocation
  2859.        from the outside.  Editing your source file can cause CHASM to
  2860.        use a different substitution text the next time you assemble.
  2861.        Internal labels are intended for macro INTERNAL use only.
  2862.  
  2863.     D. Macro Nesting
  2864.  
  2865.        Macro invocations can be nested, up to 10 deep.  Invocations
  2866.        are maintained on a stack, and each invocation has it's own
  2867.        set of parameters and internal labels.
  2868.  
  2869.        CHASM does not check for recursive macro calls.  If you call a
  2870.        macro from within itself, it's quite possible to get caught in
  2871.        an endless loop.  This can also happen indirectly, where a
  2872.        macro invokes another macro, which ends up calling the first.
  2873.        If you get caught, you can escape by hitting Ctrl-Break.
  2874.  
  2875.        Experienced programmers can use macro recursion along with
  2876.        expressions and conditional assembly to create some really
  2877.        elegant macros.  However, this is definitely not for beginners
  2878.        or the faint of heart.  Enter at your own risk.
  2879.  
  2880.  
  2881.  
  2882.  
  2883.  
  2884.  
  2885.  
  2886.  
  2887.  
  2888.  
  2889.  
  2890.  
  2891.  
  2892.  
  2893.  
  2894.  
  2895.  
  2896.  
  2897.  
  2898.  
  2899.                                                                    43
  2900.  
  2901.     E. Conditional Macro Expansion
  2902.  
  2903.        This advanced feature allows you to write general purpose
  2904.        macros which expand in different ways based on the parameters
  2905.        used on the invocation.
  2906.  
  2907.        For example, suppose you wanted to write a macro to do
  2908.        operating system calls.  Many of the DOS functions just load
  2909.        the function number into AH, then call DOS with an interrupt.
  2910.        Here's a macro to do this:
  2911.  
  2912.        doscall  macro
  2913.                 mov ah, %1
  2914.                 int 21H
  2915.                 endm
  2916.  
  2917.        Given the above definition, "DOSCALL 1" will expand into a
  2918.        call to DOS function #1, keyboard input.
  2919.  
  2920.        Unfortunately, not all DOS calls are quite so simple.  For
  2921.        example, the call for printing a string to the console
  2922.        requires that the offset of the string be loaded into DX.
  2923.        Different system calls are going to require somewhat different
  2924.        handling.  One approach would be to write separate macros for
  2925.        each function.  However, with 87 different functions in DOS 2,
  2926.        this starts to get unwieldy.
  2927.  
  2928.        A more general approach is to incorporate some "intelligence"
  2929.        into the macro, and let it expand differently for different
  2930.        DOS functions.  Here's a slightly more general macro, which
  2931.        loads DX whenever the "print string" function is requested:
  2932.  
  2933.        doscall  macro
  2934.                 mov ah, %1
  2935.                 ife %1 9
  2936.                    mov dx, offset(%2)
  2937.                 endif
  2938.                 int 21H
  2939.                 endm
  2940.  
  2941.  
  2942.  
  2943.  
  2944.  
  2945.  
  2946.  
  2947.  
  2948.  
  2949.  
  2950.  
  2951.  
  2952.  
  2953.  
  2954.  
  2955.  
  2956.  
  2957.  
  2958.  
  2959.  
  2960.  
  2961.  
  2962.  
  2963.  
  2964.  
  2965.                                                                    44
  2966.  
  2967.        "IFE" is short for "If Equal".  The "IFE" and "ENDIF" bracket
  2968.        a line of macro code which will be included during expansion
  2969.        only if the "IFE" statement is satisfied.  In this example,
  2970.        the MOV DX statement will be included only if the first
  2971.        parameter is equal to 9.  The enclosed line is indented in
  2972.        this example to help show the structure of the macro, but
  2973.        indentation is not required.
  2974.  
  2975.        Given the above definition, "DOSCALL 1" expands to only two
  2976.        lines:
  2977.  
  2978.           mov ah, 1
  2979.           int 21H
  2980.  
  2981.       However, "DOSCALL 9, STRING" expands to three lines:
  2982.  
  2983.           mov ah, 9
  2984.           mov dx, offset(string)
  2985.           int 21H
  2986.  
  2987.        CHASM supports twelve different conditional test statements.
  2988.        They are:
  2989.  
  2990.             IFE       "if equal"
  2991.             IFNE      "if not equal"
  2992.             IFGT      "if greater than"
  2993.             IFGE      "if greater than or equal"
  2994.             IFLE      "if less than or equal"
  2995.             IFLT      "if less than"
  2996.             IFB       "if blank"
  2997.             IFNB      "if not blank"
  2998.             IFREG     "if a register"
  2999.             IFREG8    "if an 8 bit register"
  3000.             IFREG16   "if a 16 bit register"
  3001.             IFSEGREG  "if a segment register"
  3002.  
  3003.        Most of the conditionals take two operands, and perform a
  3004.        comparison.  The operands are evaluated, and their values are
  3005.        compared according to the condition being tested.  Strings are
  3006.        compared in the normal alphabetical order sense.  Examples:
  3007.  
  3008.             IFE   15, 0FH       ;is true
  3009.             IFGT  'ABCD' 'EFGH' ;is false
  3010.             IFLE  20H, 128      ;is true
  3011.  
  3012.  
  3013.  
  3014.  
  3015.  
  3016.  
  3017.  
  3018.  
  3019.  
  3020.  
  3021.  
  3022.  
  3023.  
  3024.  
  3025.  
  3026.  
  3027.  
  3028.  
  3029.  
  3030.  
  3031.                                                                    45
  3032.  
  3033.        IFB and IFNB require only one operand, which should be a dummy
  3034.        parameter.  These conditionals test whether the parameter was
  3035.        left "blank" or if a replacement was provided on the
  3036.        invocation.
  3037.  
  3038.        The IFREG conditionals take one operand.  They return true if
  3039.        the operand is a register in the following sets:
  3040.  
  3041.             IFREG:    any register
  3042.             IFREG8:   AH, AL, BH, BL, CH, CL, DH, DL
  3043.             IFREG16:  AX, BX, CX, DX, DI, SI, BP, SP
  3044.             IFSEGREG: CS, DS, ES, SS
  3045.  
  3046.        You can place as many lines as you like between an IF
  3047.        statement and the ENDIF.  All will be included if the
  3048.        condition tested is true, and none will be included if it's
  3049.        false.
  3050.  
  3051.        An optional "ELSE" construct is also provided.  Statements
  3052.        after the ELSE get included only if the tested condition is
  3053.        false. CHASM's conditional assembly syntax can be summarized
  3054.        as follows:
  3055.  
  3056.            IF.....            ;if statement with parameter(s)
  3057.              s1                  ;statements included if true
  3058.              s2                  ;    "         "      "   " 
  3059.            ELSE               ;end of "true" option, begin "false"
  3060.              s3                  ;statements included if false
  3061.              s4                  ;    "         "      "   "
  3062.            ENDIF              ;end of conditional assembly
  3063.  
  3064.        IF statements can be nested, up to 10 deep.  During nesting,
  3065.        CHASM assumes that ELSEs are paired with the latest unfinished
  3066.        IF statement.  For example:
  3067.  
  3068.        example macro
  3069.                ife %1, 1
  3070.                   db 'Outer IF is true'
  3071.                   ifb %2
  3072.                      'Inner IF is true'
  3073.                   else
  3074.                      'Where do I belong?'
  3075.                   endif
  3076.                endif
  3077.  
  3078.  
  3079.  
  3080.  
  3081.  
  3082.  
  3083.  
  3084.  
  3085.  
  3086.  
  3087.  
  3088.  
  3089.  
  3090.  
  3091.  
  3092.  
  3093.  
  3094.  
  3095.  
  3096.  
  3097.                                                                    46
  3098.  
  3099.        "EXAMPLE 1, 5" expands to:
  3100.  
  3101.               db 'Outer IF is true'
  3102.               db 'Where do I belong?'
  3103.  
  3104.        But "EXAMPLE 2" produces no expansion at all.
  3105.  
  3106.        This is easiest to follow if you use "structured" indenting
  3107.        when writing the macro, as in the example above. Remember,
  3108.        however, that CHASM ignores indenting and follows the
  3109.        "latest unfinished" rule in figuring out which IF gets the
  3110.        ELSE.  Don't fool yourself with improper indentation.
  3111.  
  3112.     F. Final Notes:
  3113.  
  3114.        The conditional assembly pseudo-ops are not restricted to use
  3115.        only in macros, although there aren't that many useful
  3116.        non-macro applications.
  3117.  
  3118.        CHASM won't recursively expand parameters.  For example:
  3119.  
  3120.            RECUR MACRO
  3121.                  XOR %1, %2
  3122.                  ENDM
  3123.  
  3124.                  RECUR AX, %1
  3125.  
  3126.        expands to:
  3127.  
  3128.                 XOR AX, %1   ;actual expansion
  3129.  
  3130.        NOT to:
  3131.  
  3132.                 XOR AX, AX   ;won't happen
  3133.  
  3134.        Like equates and structures, macro definitions should all be
  3135.        placed at the beginning of your programs, before the macro
  3136.        gets invoked.  If you invoke a macro before it's defined, a
  3137.        phase error will occur.
  3138.  
  3139.  
  3140.  
  3141.  
  3142.  
  3143.  
  3144.  
  3145.  
  3146.  
  3147.  
  3148.  
  3149.  
  3150.  
  3151.  
  3152.  
  3153.  
  3154.  
  3155.  
  3156.  
  3157.  
  3158.  
  3159.  
  3160.  
  3161.  
  3162.  
  3163.                                                                    47
  3164.  
  3165.        Macro definitions are stored and expanded blindly by CHASM,
  3166.        with no syntax checking.  Dummy parameter symbols can appear
  3167.        in any of the input line fields.  Any errors in a macro
  3168.        definition will only become evident when CHASM expands the
  3169.        macro and attempts to assemble the result.
  3170.  
  3171.        In keeping with the "shorthand" philosophy of macros, the
  3172.        results of macro expansion don't normally appear on the
  3173.        listing.  If you want to see the expansion for debugging
  3174.        purposes, insert a LIST pseudo-op as the first line of the
  3175.        macro definition.
  3176.  
  3177.        Once you start writing macros, you might find it useful to
  3178.        gather them together into a single file.  You can then pull
  3179.        this file into the beginning of all your programs with an
  3180.        INCLUDE pseudo-op.  Macros which don't get invoked won't add
  3181.        anything to the object code produced, and you'll save yourself
  3182.        the trouble of typing in the ones you *do* need.  If you put a
  3183.        NOLIST at the beginning and a LIST at the end of your INCLUDE
  3184.        file, you don't even have to look at the definitions on your
  3185.        listings.
  3186.  
  3187.  
  3188.  
  3189.  
  3190.  
  3191.  
  3192.  
  3193.  
  3194.  
  3195.  
  3196.  
  3197.  
  3198.  
  3199.  
  3200.  
  3201.  
  3202.  
  3203.  
  3204.  
  3205.  
  3206.  
  3207.  
  3208.  
  3209.  
  3210.  
  3211.  
  3212.  
  3213.  
  3214.  
  3215.  
  3216.  
  3217.  
  3218.  
  3219.  
  3220.  
  3221.  
  3222.  
  3223.  
  3224.  
  3225.  
  3226.  
  3227.  
  3228.  
  3229.                                                                    48
  3230.  
  3231.     >>Structures<<
  3232.  
  3233.     ==>Advanced version only.
  3234.  
  3235.     Structures are an advanced feature.  Beginners may wish to skip
  3236.     this section until they become more experienced with CHASM and
  3237.     assembly language programming.
  3238.  
  3239.     CHASM's structure capability allows you to generate a "template"
  3240.     with which to organize repetitive data structures.  As an example
  3241.     of a repetitive data structure, consider a phone list.  Each
  3242.     entry in the list has three components:
  3243.  
  3244.          Name    - 20 characters
  3245.          Address - 50 characters
  3246.          Phone   - 10 characters
  3247.  
  3248.     Each entry thus uses a total of 80 bytes of storage.  To declare
  3249.     a list with 500 entries, you would declare 80 x 500 = 4000 bytes:
  3250.  
  3251.          PHONELIST  DS  4000   ;500 entries @ 80 bytes/entry
  3252.  
  3253.     That's easy enough, but now what's the offset of the 346th
  3254.     address field?  This is starting to get confusing, and time
  3255.     consuming to figure out.
  3256.  
  3257.     Furthermore, hard-coding numbers (like that 4000, above) into a
  3258.     program is never a good idea.  What's going to happen when you
  3259.     decide to add a zip code field, or make more room in the name
  3260.     field because you just met Alexandria Zbrievskivich?  You'd have
  3261.     to go through and change by hand each number which depended on
  3262.     the actual layout of your data.  Murphy's law guarantees that
  3263.     it'll take somewhere between "several" and "too many" assemblies
  3264.     to find them all.
  3265.  
  3266.     Structures allow you to set up a symbolic template which makes it
  3267.     much easier to manage structured data like this phone list.  By
  3268.     using symbols defined in the structure, rather than bare numbers,
  3269.     a change in data structure doesn't mean a frantic search
  3270.     throughout your entire program to make corrections.  If you
  3271.     change the structure definition, the symbols take on new values
  3272.     automatically.
  3273.  
  3274.  
  3275.  
  3276.  
  3277.  
  3278.  
  3279.  
  3280.  
  3281.  
  3282.  
  3283.  
  3284.  
  3285.  
  3286.  
  3287.  
  3288.  
  3289.  
  3290.  
  3291.  
  3292.  
  3293.  
  3294.  
  3295.                                                                    49
  3296.  
  3297.     Here's what the phone list structure looks like:
  3298.  
  3299.          LISTENTRY  STRUC
  3300.          NAME       DS 20
  3301.          ADDRESS    DS 50
  3302.          PHONE      DS 10
  3303.                     ENDSTRUC
  3304.  
  3305.     Note the STRUC and ENDSTRUC statements.  They mark the beginning
  3306.     and end of the structure, and give it a name (LISTENTRY).
  3307.  
  3308.     Within the structure are storage defining pseudo-ops.  DS is used
  3309.     in this example, but DB and DW could also be used.  ORG can be
  3310.     used within a structure, but any 8088 instruction will result in
  3311.     an diagnostic message and termination of the structure
  3312.     definition.
  3313.  
  3314.     Inside a structure, the storage defining pseudo-ops
  3315.     behave somewhat differently than normal.  No actual storage is
  3316.     set aside, but CHASM keeps track of how much space would normally
  3317.     be declared.
  3318.  
  3319.     Labels on pseudo-ops get assigned values equal to their offset
  3320.     within the *structure*, not within the program as a whole.  Also,
  3321.     CHASM will treat the labels as immediate operands, rather than
  3322.     memory locations.  The result of the structure given above is to
  3323.     generate three immediate operands, with the following values:
  3324.  
  3325.          NAME    =  0
  3326.          ADDRESS = 20
  3327.          PHONE   = 70
  3328.  
  3329.     CHASM does one other piece of useful book-keeping during
  3330.     structure definitions.  If a label appears on the STRUC
  3331.     pseudo-op, it gets treated as an immediate operand, whose value
  3332.     is equal to the total length of the structure.
  3333.  
  3334.     You can either use the STRUC label directly as an operand, or if
  3335.     you like "pretty" code, use the LENGTH operator on it.  In this
  3336.     example, both LISTENTRY and LENGTH(LISTENTRY) are immediate
  3337.     operands of value 80.
  3338.  
  3339.     (Inside note: LENGTH is a null operator, provided mainly for
  3340.     aesthetic reasons.  Using LENGTH will often make your code more
  3341.     readable, but is equivalent to using just the label itself.)
  3342.  
  3343.  
  3344.  
  3345.  
  3346.  
  3347.  
  3348.  
  3349.  
  3350.  
  3351.  
  3352.  
  3353.  
  3354.  
  3355.  
  3356.  
  3357.  
  3358.  
  3359.  
  3360.  
  3361.                                                                    50
  3362.  
  3363.     Like equates and macros, structures should be placed at the
  3364.     beginning of your programs before any machine instructions,
  3365.     otherwise phase errors can occur.  If you *do* embed structures
  3366.     inside your program, you can eliminate any phase errors by using
  3367.     the LENGTH function to reference any of the immediate operands
  3368.     generated by the embedded structure.
  3369.  
  3370.     The immediate operands generated during a structure definition
  3371.     can be very useful in writing your program.  Following the phone
  3372.     list example, here's a better way to declare storage for the
  3373.     list:
  3374.  
  3375.        NUMENTRYS  EQU 500
  3376.        PHONELIST  DS  LISTENTRY*NUMENTRYS ;500 entries of length
  3377.                                           ;defined by the structure.
  3378.  
  3379.     Now if you add another field to the structure, PHONELIST will
  3380.     automatically increase in size.
  3381.  
  3382.     The 8088's indirect addressing modes, coupled with structures,
  3383.     make a very powerful combination for accessing structured data in
  3384.     memory.  Suppose AX contains the number of the entry you want to
  3385.     work on.  You can calculate the address of the entry as follows:
  3386.  
  3387.         MOV BX, LENGTH(LISTENTRY)    ;length per entry
  3388.         MUL AX, BX                   ;times entry number
  3389.         ADD AX, OFFSET(PHONELIST)    ;plus the starting offset
  3390.         MOV BX, AX                   ;BX <== frame pointer
  3391.  
  3392.     BX is now a "frame pointer" - it points to the beginning of the
  3393.     desired entry.  You can access the various parts of the entry
  3394.     using the optional displacement field in the indirect address.
  3395.     For example, here's how you would store the letter 'A' into the
  3396.     first byte of the address field:
  3397.  
  3398.          MOV  ADDRESS[BX], 'A'
  3399.  
  3400.     As another example, the following line reads the third letter of
  3401.     the name into the AL register:
  3402.  
  3403.          MOV  AL, NAME+3[BX]
  3404.  
  3405.  
  3406.  
  3407.  
  3408.  
  3409.  
  3410.  
  3411.  
  3412.  
  3413.  
  3414.  
  3415.  
  3416.  
  3417.  
  3418.  
  3419.  
  3420.  
  3421.  
  3422.  
  3423.  
  3424.  
  3425.  
  3426.  
  3427.                                                                    51
  3428.  
  3429.     The first entry in a structure almost invariably has value 0.
  3430.     CHASM "optimizes" indirect addresses with structure-generated
  3431.     constants equal to zero, generating the no-offset form of the
  3432.     address.  In this example:
  3433.  
  3434.         MOV AX, NAME[BX]
  3435.  
  3436.     actually assembles as MOV AX, [BX] rather than MOV AX, 0[BX]
  3437.     The resulting code is more compact, and runs faster.
  3438.  
  3439.     The more complicated indirect modes can be used to scan through
  3440.     or point within the fields.  The following program fragment gets
  3441.     the fourth digit in the phone number:
  3442.  
  3443.          MOV DI, 4             ;specify 4th digit
  3444.          MOV AL, PHONE[BX+DI] ;read it into AL
  3445.  
  3446.     Often times, you'll want to process entries sequentially.  To
  3447.     move to the next entry, you just add the length of the entry to
  3448.     the frame pointer:
  3449.  
  3450.          ADD   BX, LENGTH(LISTENTRY)    ;point to next entry
  3451.  
  3452.     The preceding examples should give you a feel for what you can
  3453.     do with structures, but do not exhaust all the possibilities.
  3454.     Experiment with this feature, and many of your programs will be
  3455.     both more readable and more easily modified.
  3456.  
  3457.  
  3458.  
  3459.  
  3460.  
  3461.  
  3462.  
  3463.  
  3464.  
  3465.  
  3466.  
  3467.  
  3468.  
  3469.  
  3470.  
  3471.  
  3472.  
  3473.  
  3474.  
  3475.  
  3476.  
  3477.  
  3478.  
  3479.  
  3480.  
  3481.  
  3482.  
  3483.  
  3484.  
  3485.  
  3486.  
  3487.  
  3488.  
  3489.  
  3490.  
  3491.  
  3492.  
  3493.                                                                    52
  3494.  
  3495.     >>8087 Support<<
  3496.  
  3497.     ===> Advanced version only.
  3498.  
  3499.     In addition to the normal 8088 instructions, CHASM's Advanced
  3500.     version supports all the 8087 mnemonics.  Look in the appendices
  3501.     for a list available instructions.
  3502.  
  3503.     Several books describing the functions of the 8087 instructions
  3504.     are available.  CHASM's 8087 support is based on Appendix D of
  3505.     Intel's 8087 Support Library, and the book "Assembly Language
  3506.     Programming for the IBM Personal Computer" by David J. Bradley
  3507.     (Prentice-Hall, 1984).
  3508.  
  3509.     ALL the 8087 instructions that reference memory for a real or
  3510.     integer quantity are ambiguous as to the size of operand.
  3511.     Integers can be Word (2 bytes), Short (4 bytes) , or Long (8
  3512.     bytes).  Reals can be Short (4 bytes), Long (8 bytes) or
  3513.     Temporary Real (10 bytes).
  3514.  
  3515.     As with 8088 memory references, CHASM resolves ambiguities using
  3516.     a suffix.  The following suffixes can be added to mnemonics to
  3517.     specify operand size:
  3518.  
  3519.        W: word
  3520.        S: short
  3521.        L: long
  3522.        T: temporary real
  3523.  
  3524.     Here are some examples of using suffixes:
  3525.  
  3526.        FADD   [200H]    ;wrong! ambiguous memory reference
  3527.        FADDT  [200H]    ;add 10 byte temporary real
  3528.        FILD   CS:[DI]   ;wrong! ambiguous memory reference
  3529.        FILDW  CS:[DI]   ;load 2 byte integer
  3530.  
  3531.     CHASM automatically generates a WAIT instructions prior to most
  3532.     8087 instructions.  The only exceptions are the "No Wait"
  3533.     instructions with a "N" as the mnemonic's second letter.
  3534.     Examples:
  3535.  
  3536.         FYL2X   ;automatically preceded by WAIT
  3537.         FNCLEX  ;no wait form of FCLEX
  3538.  
  3539.  
  3540.  
  3541.  
  3542.  
  3543.  
  3544.  
  3545.  
  3546.  
  3547.  
  3548.  
  3549.  
  3550.  
  3551.  
  3552.  
  3553.  
  3554.  
  3555.  
  3556.  
  3557.  
  3558.  
  3559.                                                                    53
  3560.  
  3561.     If you'd prefer to manually add WAITs only where needed to
  3562.     synchronize critical instructions, the WAITOFF pseudo-op disables
  3563.     CHASM's automatic WAIT assembly.  Using fewer WAITs allows the
  3564.     8088 and 8087 to run in parallel more often, giving better
  3565.     performance.  Make sure you synchronize with a WAIT before
  3566.     allowing the 8088 to access a location being modified by the
  3567.     8087.  You can turn CHASM's automatic WAIT assembly back on using
  3568.     a WAITON pseudo-op.
  3569.  
  3570.     You must use the operand modifier form for segment overrides on
  3571.     8087 instructions.  A separate SEG instruction will modify
  3572.     CHASM's automatically generated WAIT instruction, and won't
  3573.     affect the intended 8087 instruction.  Example:
  3574.  
  3575.         SEG CS
  3576.         FLDS [100H]     ;wrong!
  3577.         FLDS CS:[100H]  ;correct
  3578.  
  3579.  
  3580.  
  3581.  
  3582.  
  3583.  
  3584.  
  3585.  
  3586.  
  3587.  
  3588.  
  3589.  
  3590.  
  3591.  
  3592.  
  3593.  
  3594.  
  3595.  
  3596.  
  3597.  
  3598.  
  3599.  
  3600.  
  3601.  
  3602.  
  3603.  
  3604.  
  3605.  
  3606.  
  3607.  
  3608.  
  3609.  
  3610.  
  3611.  
  3612.  
  3613.  
  3614.  
  3615.  
  3616.  
  3617.  
  3618.  
  3619.  
  3620.  
  3621.  
  3622.  
  3623.  
  3624.  
  3625.                                                                    54
  3626.  
  3627.     >>Outside the Program Segment<<
  3628.  
  3629.     As mentioned previously, CHASM does not support multiple segment
  3630.     definitions.  Provision is made for limited access outside of the
  3631.     program segment, however.
  3632.  
  3633.     A. Memory References:
  3634.        To access memory outside the program segment, you move a new
  3635.        segment address into the DS register, then address using
  3636.        offsets in the new segment.  The memory option of the EQU
  3637.        pseudo-op allows you to give a variable name to offsets in
  3638.        other segments. For example, to access DOS's equipment flag:
  3639.  
  3640.           BIOS_DATA   EQU  40H
  3641.           EQUIP_FLAG  EQU  [0010H]
  3642.                       MOV  AX,BIOS_DATA  ;can't move immed. to DS
  3643.                       MOV  DS,AX
  3644.                       MOV  AX,EQUIP_FLAG ;get bios equipment flag
  3645.  
  3646.     B. Code Branching:
  3647.        CHASM supports 4 instructions for branching outside the
  3648.        program segment.
  3649.  
  3650.        1. Direct CALL and JMP
  3651.  
  3652.           New values for the PC and CS registers are included in the
  3653.           instruction as two immediate operands.  Example:
  3654.  
  3655.           BIOS         EQU  0F000H            ;RAM bios segment
  3656.           DISKETTE_IO  EQU  0EC59H            ;disk handler
  3657.                        JMP  DISKETTE_IO,BIOS
  3658.  
  3659.        2. Indirect CALLF and JMPF
  3660.  
  3661.           Four consecutive bytes in memory are initialized with new
  3662.           values for the PC and CS registers.  The CALLF or JMPF then
  3663.           references the address of the new values.  Example:
  3664.  
  3665.           BIOS        EQU   0F000H           ;RAM bios segment
  3666.           PRINTER_IO  EQU   0EFD2H           ;printer routine
  3667.                       MOV   [DI],PRINTER_IO
  3668.                       MOV   2[DI],BIOS
  3669.                       CALLF [DI]
  3670.  
  3671.  
  3672.  
  3673.  
  3674.  
  3675.  
  3676.  
  3677.  
  3678.  
  3679.  
  3680.  
  3681.  
  3682.  
  3683.  
  3684.  
  3685.  
  3686.  
  3687.  
  3688.  
  3689.  
  3690.  
  3691.                                                                    55
  3692.  
  3693.     >>Running CHASM<<
  3694.  
  3695.     A. Prompt Mode
  3696.  
  3697.        From DOS, type:
  3698.  
  3699.          CHASM
  3700.  
  3701.        If you're using the Subset version, a hello screen is printed,
  3702.        followed by the message:
  3703.  
  3704.          Hit Esc to exit, anything else to continue...
  3705.  
  3706.        Advanced CHASM skips the commercial message.
  3707.  
  3708.        You're now presented with a series of prompts:
  3709.  
  3710.           Source code file name? [.asm]
  3711.  
  3712.        Type in the name of the file which contains your program.  If
  3713.        you don't include an extension for the filename, CHASM
  3714.        assumes it to be .ASM.  If CHASM is unable to find the file,
  3715.        it will give you the option of naming another file, or
  3716.        returning to DOS.  Note that anywhere CHASM expects a
  3717.        filename, you can optionally include a drive and/or path.
  3718.  
  3719.        Assuming your file is present, CHASM prompts:
  3720.  
  3721.           Direct listing to Printer (P), Screen (S), or Disk (D)?
  3722.           [nul:]
  3723.  
  3724.        Respond with either an upper or lower case letter.  If you
  3725.        just press enter, no listing will be produced.  If you select
  3726.        "D", CHASM will prompt:
  3727.  
  3728.           Name for listing file? [fname.lst]
  3729.  
  3730.        Type in a name for the listing file.  If you just press ENTER,
  3731.        the name defaults to that of your source file, with an
  3732.        extension of .LST.
  3733.  
  3734.  
  3735.  
  3736.  
  3737.  
  3738.  
  3739.  
  3740.  
  3741.  
  3742.  
  3743.  
  3744.  
  3745.  
  3746.  
  3747.  
  3748.  
  3749.  
  3750.  
  3751.  
  3752.  
  3753.  
  3754.  
  3755.  
  3756.  
  3757.                                                                    56
  3758.  
  3759.        Listing Notes:
  3760.  
  3761.           1. The setting of the /PATH configuration switch controls
  3762.              the exact form of the default list file name.
  3763.  
  3764.           2. Regardless of where the listing is sent, error messages
  3765.              are always echoed to the screen.
  3766.  
  3767.           3. Suppressing the listing will result in faster assembly.
  3768.  
  3769.        The final prompt is:
  3770.  
  3771.           Name for object file? [fname.com]
  3772.  
  3773.        Type in a name for the assembled program.  If you just press
  3774.        ENTER, the name defaults to that of your source file, with an
  3775.        extension of .COM.
  3776.  
  3777.        Note: The setting of the /PATH configuration switch controls
  3778.              the exact form of the default object file name.
  3779.  
  3780.        CHASM now assembles your program.  A status line is maintained
  3781.        on the screen, showing how many lines have been processed,
  3782.        along with how many errors have been discovered.  CHASM makes
  3783.        two passes over your source file, outputting the listing and
  3784.        object code on the second pass.  You can pause assembly at any
  3785.        time by hitting Cntl-S (or just S).  Hitting any key then
  3786.        resumes assembly. You may abort assembly and return to DOS at
  3787.        any time by hitting Esc, Ctrl-C or Ctrl-Break.
  3788.  
  3789.        At the end of the second pass, a final summary of the assembly
  3790.        process is printed.  It will look something like:
  3791.  
  3792.           0 Error(s) detected
  3793.           0 Diagnostic(s) offered
  3794.  
  3795.        954 (3BAH) Bytes of object code generated
  3796.  
  3797.        This information should be self-explanatory.  The number of
  3798.        bytes is given in both decimal and hex format.
  3799.  
  3800.  
  3801.  
  3802.  
  3803.  
  3804.  
  3805.  
  3806.  
  3807.  
  3808.  
  3809.  
  3810.  
  3811.  
  3812.  
  3813.  
  3814.  
  3815.  
  3816.  
  3817.  
  3818.  
  3819.  
  3820.  
  3821.  
  3822.  
  3823.                                                                    57
  3824.  
  3825.        If labels appeared in your program, a dump of the symbol table
  3826.        will follow.  This lists each user-defined symbol, along with
  3827.        its value (in hex). The symbols are printed in alphabetical
  3828.        order.  Each value is preceded by a one-letter code, which
  3829.        tells the symbol's type:
  3830.  
  3831.                 P: a program location
  3832.                 M: a memory location for data
  3833.                 I: immediate data
  3834.  
  3835.        Upon exit, CHASM sets the system variable ERRORLEVEL to
  3836.        (surprise!) the total number of errors discovered in your
  3837.        source file. If you run CHASM from a batch file, you can use
  3838.        this feature to automatically invoke your text editor if
  3839.        errors were discovered.
  3840.  
  3841.     B. Expert Mode:
  3842.  
  3843.        This mode allows you to specify all i/o information on the
  3844.        command line which invokes CHASM.  The syntax is:
  3845.  
  3846.           CHASM sourcefile [p|s|d|/] [listfile|/] [objectfile]
  3847.  
  3848.        Items within brackets ([]) are optional. You may select *one*
  3849.        of any list of items separated by a bar (|).
  3850.  
  3851.        Basically, you just include on the command line all your
  3852.        responses to the normal prompts.  Each response must be
  3853.        separated from the others by either a space or comma.
  3854.  
  3855.        If you don't specify the list device/file or the object file,
  3856.        they default to NUL: and sourcename.COM respectively.  To
  3857.        represent a carriage return (to specify a default choice, but
  3858.        allow modifying a later response) use the character slash (/).
  3859.  
  3860.  
  3861.  
  3862.  
  3863.  
  3864.  
  3865.  
  3866.  
  3867.  
  3868.  
  3869.  
  3870.  
  3871.  
  3872.  
  3873.  
  3874.  
  3875.  
  3876.  
  3877.  
  3878.  
  3879.  
  3880.  
  3881.  
  3882.  
  3883.  
  3884.  
  3885.  
  3886.  
  3887.  
  3888.  
  3889.                                                                    58
  3890.  
  3891.        Expert mode examples:
  3892.  
  3893.           1. Source file is EXAMPLE.ASM, no listing, object file
  3894.              EXAMPLE.COM:
  3895.  
  3896.                 CHASM example
  3897.  
  3898.           2. Source file is SDIR.ASM, list to printer, object file
  3899.              SDIR.COM:
  3900.  
  3901.                 CHASM sdir p
  3902.  
  3903.           3. Source file is MYFILE.PRG, list to disk file MYFILE.LST,
  3904.              object file SUBR.COM:
  3905.  
  3906.                 CHASM myfile.prg d / subr.com
  3907.  
  3908.  
  3909.  
  3910.  
  3911.  
  3912.  
  3913.  
  3914.  
  3915.  
  3916.  
  3917.  
  3918.  
  3919.  
  3920.  
  3921.  
  3922.  
  3923.  
  3924.  
  3925.  
  3926.  
  3927.  
  3928.  
  3929.  
  3930.  
  3931.  
  3932.  
  3933.  
  3934.  
  3935.  
  3936.  
  3937.  
  3938.  
  3939.  
  3940.  
  3941.  
  3942.  
  3943.  
  3944.  
  3945.  
  3946.  
  3947.  
  3948.  
  3949.  
  3950.  
  3951.  
  3952.  
  3953.  
  3954.  
  3955.                                                                    59
  3956.  
  3957.     >>Error and Diagnostic Messages<<
  3958.  
  3959.     Error messages generated on pass one appear on the listing before
  3960.     any source code is printed, and mention the line number to which
  3961.     they refer.  The majority of messages occur during pass two, and
  3962.     will appear in the listing immediately prior to the line which
  3963.     caused the message.  Unless the listing itself is going to the
  3964.     screen, messages and the source line which generated them will be
  3965.     echoed there.
  3966.  
  3967.     Add Leading Zero to Hex Constant: Diagnostic.  The unknown
  3968.        symbol could be interpreted as a hexadecimal number if a
  3969.        leading zero was added.
  3970.  
  3971.     CHASM Internal Error: XX PC: YYYY or
  3972.     CHASM I/O Error: XX PC: YYYY 
  3973.        Sigh. You just discovered a problem in CHASM itself.  Please
  3974.        contact Whitman Software, following the procedure in the
  3975.        appendix on Bug Reporting.
  3976.  
  3977.     Could Use JMPS: Diagnostic.  The specified label requires an
  3978.        offset of less than 128 bytes; specifying the short jump would
  3979.        result in more compact code.  The assembled code is correct,
  3980.        however.
  3981.  
  3982.     Conditional Nested Too Deeply:  IF statements can only be nested
  3983.        10 deep.
  3984.  
  3985.     Data too Large:  You are attempting to use a word of immediate
  3986.        data where only a byte is allowed.
  3987.  
  3988.     DM out of range:  The product of the DM's operands is either
  3989.        negative, or greater than 32767.
  3990.  
  3991.     Duplicate Definition of XXX in (linenum): Pass 1 error.  An
  3992.        attempt was made to define a symbol already present in the
  3993.        symbol table.
  3994.  
  3995.     ELSE without IF: An ELSE was encountered, but no corresponding
  3996.        conditional pseudo-op was found.
  3997.  
  3998.     ENDIF without IF: An ENDIF was encountered, but no corresponding
  3999.        conditional pseudo-op was found.
  4000.  
  4001.     ENDM without MACRO:  An ENDM was encountered, but no
  4002.        corresponding MACRO was found.
  4003.  
  4004.  
  4005.  
  4006.  
  4007.  
  4008.  
  4009.  
  4010.  
  4011.  
  4012.  
  4013.  
  4014.  
  4015.  
  4016.  
  4017.  
  4018.  
  4019.  
  4020.  
  4021.                                                                    60
  4022.  
  4023.  
  4024.     ENDP without PROC: An ENDP was encountered, but no corresponding
  4025.        PROC was found.
  4026.  
  4027.     ENDSTRUC without STRUC: An ENDSTRUC was encountered, but no
  4028.        corresponding STRUC was found.
  4029.  
  4030.     EQU Without Label: No symbol was found to equate with the
  4031.        operand.
  4032.  
  4033.     File not found: XXX in (linenum).  Pass one error.  CHASM was
  4034.        unable to find the file XXX, specified in the INCLUDE
  4035.        pseudo-op.
  4036.  
  4037.     Heap Full: Too many XXX.  Usually a Pass one error.
  4038.        You've run out of memory for the symbol and macro tables.  You
  4039.        shouldn't see this message unless you have only 128K and are
  4040.        assembling a very large program.
  4041.  
  4042.     Illegal Label: XXX in (linenum). Pass one error.  The symbol
  4043.        XXX begins in column one and has as its first character a
  4044.        number, or a plus or minus sign.  Alternatively, you tried to
  4045.        use a reserved word or symbol as a label.
  4046.  
  4047.     Illegal Operation for Structure - ENDSTRUC Implied: Diagnostic.
  4048.        The current line is within a structure, and is not a storage
  4049.        defining pseudo-op.  CHASM generates an ENDSTRUC, which
  4050.        terminates the structure definition, then assembles the line
  4051.        normally.
  4052.  
  4053.     Illegal or Undefined Argument for LENGTH:  The argument for the
  4054.        LENGTH  function was not present in the symbol table as an
  4055.        immediate operand on pass 2.
  4056.  
  4057.     Illegal or Undefined Argument for OFFSET: The argument for the
  4058.        OFFSET function was not present in the symbol table as a near
  4059.        label or memory location on pass 2.
  4060.  
  4061.     Missing ENDM:  The end of the input file was encountered, and at
  4062.        least one MACRO had not been terminated by an ENDM.
  4063.  
  4064.     Missing ENDP: The end of the input file was encountered, and at
  4065.        least one PROC had not been terminated by an ENDP.
  4066.  
  4067.     Missing ENDSTRUC: The end of the input file was encountered, and
  4068.        at least one STRUC had not been terminated by an ENDSTRUC.
  4069.  
  4070.  
  4071.  
  4072.  
  4073.  
  4074.  
  4075.  
  4076.  
  4077.  
  4078.  
  4079.  
  4080.  
  4081.  
  4082.  
  4083.  
  4084.  
  4085.  
  4086.  
  4087.                                                                    61
  4088.  
  4089.  
  4090.     Multiple Segment Overrides are Illegal:  Diagnostic.  You have
  4091.        specified more than one segment override on this instruction.
  4092.        The first override is used, and the other(s) ignored.
  4093.  
  4094.     Nested INCLUDE: An INCLUDE was encountered in an INCLUDEd file.
  4095.        The INCLUDE pseudo-op cannot be nested.
  4096.  
  4097.     Nested Structure: A STRUC was encountered inside a structure.
  4098.        Structures cannot be nested.
  4099.  
  4100.     No Name For Macro:  Diagnostic.  The macro statement did not have
  4101.        a label.  CHASM is unable to give a name to the macro, and you
  4102.        will be unable to reference it.
  4103.  
  4104.     Operands Not Compatible:  The size of the two operands does not
  4105.        match.
  4106.  
  4107.     Phase Error: A label or memory location is found to have
  4108.        different values on pass 1 and pass 2.  A difficult to debug
  4109.        error: generally the problem is not caused by the statement
  4110.        which received the error message. The problem is caused by an
  4111.        improper statement before this one, but after any other labels
  4112.        (otherwise *they* would have received the error message).
  4113.  
  4114.        When phase errors are discovered, CHASM prints this message,
  4115.        then resynchronizes the location counter to match the offset
  4116.        calculated on pass one.  If further phase errors are reported,
  4117.        the line responsable for each subsequent error will be located
  4118.        between two Phase Error messages, but after any unflagged
  4119.        labels.
  4120.  
  4121.        There are four documented ways to generate phase errors.
  4122.  
  4123.        1. A previous instruction used a symbolic immediate operand
  4124.           prior to the symbol's definition.
  4125.  
  4126.        2. A previous instruction made improper use of a forward
  4127.           referenced label, either an attempt to branch into a data
  4128.           area, or to access a code area as if it was data.
  4129.  
  4130.        3. The label on the flagged statement is defined more than
  4131.           once in the program.
  4132.  
  4133.        4. A previous instruction invoked a macro prior to its
  4134.           definition.
  4135.  
  4136.  
  4137.  
  4138.  
  4139.  
  4140.  
  4141.  
  4142.  
  4143.  
  4144.  
  4145.  
  4146.  
  4147.  
  4148.  
  4149.  
  4150.  
  4151.  
  4152.  
  4153.                                                                    62
  4154.  
  4155.  
  4156.        Whitman Software would appreciate hearing about any other
  4157.        situations which cause the Phase Error message to appear.
  4158.  
  4159.     Parameter Too Large for Expansion: Diagnostic. Replacement of the
  4160.        dummy parameter would cause the macro line to exceed CHASM's
  4161.        internal 255 character limit for manipulating strings.
  4162.        Generally this message will be accompanied by the "Source Line
  4163.        Truncated" message, warning that a line has exceeded the
  4164.        allowed 80 columns.
  4165.  
  4166.     Procedures Nested Too Deeply: Procedures may be
  4167.        nested no more than 10 deep.
  4168.  
  4169.     Source Line Truncated:  The length of the input line exceeded 80
  4170.        characters.
  4171.  
  4172.     Specify Word or Byte Operation: Diagnostic.  CHASM suggests that
  4173.        the Syntax Error might be resolved by adding the suffix "B" or
  4174.        "W" to the instruction mnemonic.  Most, but not all, ambiguous
  4175.        memory references are flagged with this diagnostic.
  4176.  
  4177.     Syntax Error: (OP) (DEST), (SOURCE).  CHASM was unable to find a
  4178.       version of the instruction (OP) which allows the operands
  4179.       (DEST) and (SOURCE).  Either the instruction doesn't exist, or
  4180.       it is an inappropriate choice for the given operands.  The (OP)
  4181.       (Dest), (Source) is a reconstruction of your source line based
  4182.       on how CHASM parsed it.  A comparison of the reconstruction and
  4183.       your original source code will sometimes help pinpoint the
  4184.       error.
  4185.  
  4186.       Syntax Error messages are followed by two diagnostics which
  4187.       spell out in words CHASM's best guess about the operands.
  4188.       Again, a comparison between CHASM's guesses and what you
  4189.       really meant can help find the problem.
  4190.  
  4191.     Too Far For Short Jump: The displacement to the specified label
  4192.        is not in the range -128 to +127.
  4193.  
  4194.     Undefined Operand for EQU: Any operands on an EQU statement must
  4195.        have been previously defined.
  4196.  
  4197.     Undefined Symbol XXX: The symbol XXX was used as an operand, but
  4198.        never appeared as a label, and is not a predefined symbol.
  4199.  
  4200.  
  4201.  
  4202.  
  4203.  
  4204.  
  4205.  
  4206.  
  4207.  
  4208.  
  4209.  
  4210.  
  4211.  
  4212.  
  4213.  
  4214.  
  4215.  
  4216.  
  4217.  
  4218.  
  4219.                                                                    63
  4220.  
  4221.     Unrecognized Operand XXX: XXX is used in the DB or DW operand
  4222.        list, but is not a valid immediate operand. (or string, in the
  4223.        case of DB).
  4224.  
  4225.  
  4226.  
  4227.  
  4228.  
  4229.  
  4230.  
  4231.  
  4232.  
  4233.  
  4234.  
  4235.  
  4236.  
  4237.  
  4238.  
  4239.  
  4240.  
  4241.  
  4242.  
  4243.  
  4244.  
  4245.  
  4246.  
  4247.  
  4248.  
  4249.  
  4250.  
  4251.  
  4252.  
  4253.  
  4254.  
  4255.  
  4256.  
  4257.  
  4258.  
  4259.  
  4260.  
  4261.  
  4262.  
  4263.  
  4264.  
  4265.  
  4266.  
  4267.  
  4268.  
  4269.  
  4270.  
  4271.  
  4272.  
  4273.  
  4274.  
  4275.  
  4276.  
  4277.  
  4278.  
  4279.  
  4280.  
  4281.  
  4282.  
  4283.  
  4284.  
  4285.                                                                    64
  4286.  
  4287.     >>Execution of Assembled Programs<<
  4288.  
  4289.     A. Object code format
  4290.  
  4291.        The object code file produced by CHASM is in the form of a
  4292.        memory image, exactly as will be present in your computer at
  4293.        run time.  No link step is required.  Provided that the segment
  4294.        registers are set correctly, the architecture of the 8088
  4295.        guarantees that code is self-relocating, and will run correctly
  4296.        loaded anywhere in memory.  Storing a program as an exact image
  4297.        of memory at run time is called the COM format by IBM.
  4298.  
  4299.        This COM format is *not* that produced by the IBM assembler.
  4300.        The output of the IBM assembler is in the form of an "object
  4301.        module" suitable for input to the linker.  The object module
  4302.        is not directly executable, but must first be "filtered"
  4303.        through the linker.  This adds an extra step to the process of
  4304.        producing a working program, but gives you the option of
  4305.        combining multiple object modules into one program.  The
  4306.        resulting linked program is *still* not a memory image, but
  4307.        has a header which is used to perform relocation during
  4308.        loading.  This linked program plus header is called the EXE
  4309.        format by IBM.
  4310.  
  4311.     B. Running Assembled Programs From DOS
  4312.  
  4313.        DOS provides a loader for running machine language programs.
  4314.        To run a program, you merely type its name, without the
  4315.        extension.  This is what you're doing every time you use a DOS
  4316.        external command such as FORMAT or CHKDSK.  In fact, the COM
  4317.        format is named after "external COMmand".
  4318.  
  4319.        When DOS loads a program, it examines the file extension to
  4320.        determine what format the file is in, either COM or EXE.  This
  4321.        is why CHASM defaults to using the extension .COM for your
  4322.        object file.  If you plan to run the program from DOS, don't
  4323.        change the extension.
  4324.  
  4325.        For COM programs, DOS builds a 255 byte long "program segment
  4326.        prefix" and sets the segment registers to point to this PSP.
  4327.        The contents of the file are then loaded verbatim right after
  4328.        the PSP, at offset hex 100 in the segment defined by the
  4329.        segment registers.  As soon as loading is complete, your
  4330.        program is executed starting with the instruction at hex 100.
  4331.  
  4332.  
  4333.  
  4334.  
  4335.  
  4336.  
  4337.  
  4338.  
  4339.  
  4340.  
  4341.  
  4342.  
  4343.  
  4344.  
  4345.  
  4346.  
  4347.  
  4348.  
  4349.  
  4350.  
  4351.                                                                    65
  4352.  
  4353.        Although you can totally ignore the PSP, you should read pages
  4354.        E-3 through E-11 of the DOS manual to see what DOS puts there
  4355.        for you.  It turns out there are some real goodies which your
  4356.        program might want to use.
  4357.  
  4358.        When your program is done, it must transfer control back to
  4359.        DOS, otherwise the 8088 will continue to fetch what it
  4360.        believes are instructions from whatever garbage or bit-hash
  4361.        happens to follow your program in memory.  The easiest way to
  4362.        return to DOS is to execute the instruction:
  4363.  
  4364.          INT 20H
  4365.  
  4366.        This is the vectored interrupt reserved by DOS for program
  4367.        termination.
  4368.  
  4369.        While we're on the topic of vectored interrupts, you would be
  4370.        well rewarded to study both the DOS Technical Reference and
  4371.        Hardware Technical Reference Manuals to find out what happens
  4372.        when you execute some of the other interrupts.  Some very
  4373.        useful functions, such as file handling and screen i/o, are
  4374.        available at the machine language level through this
  4375.        mechanism.  Information on interrupts is also available in
  4376.        Peter Norton's book "Programmer's Guide to the IBM PC", which
  4377.        is cheaper than buying both of IBM's reference manuals, and
  4378.        also more readable.
  4379.  
  4380.        Looking at things the other way, by changing the interrupt
  4381.        vector for a given function to point to your own code, you can
  4382.        override the way DOS or the BIOS does something, and do it
  4383.        your way.  DOS even provides a method (via interrupt 27H) by
  4384.        which your new code can be grafted onto DOS, and not be
  4385.        overwritten by other programs.
  4386.  
  4387.     C. Debugging Assembled Programs
  4388.  
  4389.        IBM provides an excellent utility with DOS, called DEBUG.COM.
  4390.        By specifying your program's name as a parameter when invoking
  4391.        DEBUG, you can observe your program execute with DEBUG's trace
  4392.        and other functions.  To debug your program, from DOS type:
  4393.  
  4394.           DEBUG progname.COM
  4395.  
  4396.  
  4397.  
  4398.  
  4399.  
  4400.  
  4401.  
  4402.  
  4403.  
  4404.  
  4405.  
  4406.  
  4407.  
  4408.  
  4409.  
  4410.  
  4411.  
  4412.  
  4413.  
  4414.  
  4415.  
  4416.  
  4417.                                                                    66
  4418.  
  4419.        DEBUG builds a PSP and loads your program just like DOS does,
  4420.        but you have the added power of the debugging commands to
  4421.        monitor your program while it runs.  See chapter 6 of the DOS
  4422.        manual for more details about using DEBUG.
  4423.  
  4424.        On the topic of debugging, I can recommend most highly a
  4425.        program called TRACE86, from Morgan Computing (10400 N.
  4426.        Central Expressway, Suite 210, Dallas, TX 75231).  The program
  4427.        replaces DEBUG, and although rather steeply priced, makes the
  4428.        IBM debugger look silly.  I've been using TRACE86 for some
  4429.        time now, and wouldn't be without it.
  4430.  
  4431.     D. Using Assembled Programs in BASIC
  4432.  
  4433.        To incorporate a machine language subroutine in a BASIC
  4434.        program, write it in assembly language, then assemble it with
  4435.        CHASM.  You should read page C-7 of the BASIC manual for some
  4436.        conventions to use in writing your subroutine.  In particular,
  4437.        note that you must declare the routine to CHASM as a FAR
  4438.        procedure using the PROC pseudo-op, and that the last
  4439.        instruction of the routine should be a RET.
  4440.  
  4441.        Unlike programs which are run directly from DOS, your routine
  4442.        will not be preceded by a program segment prefix.  You should
  4443.        prevent CHASM from leaving room for a PSP by putting an ORG 0
  4444.        pseudo-op at the beginning of your routine. If you don't
  4445.        include the ORG, memory references will not be assembled
  4446.        correctly.  Example:
  4447.  
  4448.             ORG  0    ;no psp
  4449.        SUBR PROC FAR  ;far procedure
  4450.             ...       ;body of subroutine
  4451.             RET
  4452.             ENDP
  4453.  
  4454.        CHASM supports two methods for getting assembled routines into
  4455.        BASIC programs.  The methods differ in whether the routine is
  4456.        included in the BASIC program file, or in a separate file.
  4457.  
  4458.        A utility program called COM2DATA is provided for including
  4459.        machine language within BASIC program files.  The program is
  4460.        distributed in source code form (file COM2DATA.ASM) and must
  4461.        be assembled with CHASM prior to use.  The program functions
  4462.        as a DOS 2 filter, reading a COM file in from the standard
  4463.        input, and writing a series of BASIC DATA statements to the
  4464.        standard output.
  4465.  
  4466.  
  4467.  
  4468.  
  4469.  
  4470.  
  4471.  
  4472.  
  4473.  
  4474.  
  4475.  
  4476.  
  4477.  
  4478.  
  4479.  
  4480.  
  4481.  
  4482.  
  4483.                                                                    67
  4484.  
  4485.  
  4486.        COM2DATA's syntax is as follows:
  4487.  
  4488.          COM2DATA [<infile] [>outfile] [linenum]
  4489.  
  4490.        You specify the input and output files as with any DOS 2
  4491.        filter.  The linenum parameter sets the starting line number
  4492.        used on the BASIC code produced.  If you don't specify
  4493.        linenum, it defaults to 1000.
  4494.  
  4495.        If you MERGE the file of DATA statements into your BASIC
  4496.        program, the program can then READ the data and POKE it into
  4497.        memory.  An example program to do this is given on page C-6 of
  4498.        the BASIC manual.  An alternative approach would be to store
  4499.        the routine in a string variable, which could later be located
  4500.        with the VARPTR function. 
  4501.  
  4502.        If you would prefer to keep your machine language subroutine
  4503.        in a separate file, include a BSAVE pseudo-op somewhere within
  4504.        your assembly language source code.  CHASM will build a header
  4505.        on the object code produced, which will mimic that built by
  4506.        BASIC's BSAVE command.  The resulting file may be BLOADed by
  4507.        BASIC to any location in memory.
  4508.  
  4509.        You transfer control to your routine with either the USR
  4510.        function, or the CALL statement.  Syntax for these statements
  4511.        can be found in the BASIC manual.
  4512.  
  4513.  
  4514.  
  4515.  
  4516.  
  4517.  
  4518.  
  4519.  
  4520.  
  4521.  
  4522.  
  4523.  
  4524.  
  4525.  
  4526.  
  4527.  
  4528.  
  4529.  
  4530.  
  4531.  
  4532.  
  4533.  
  4534.  
  4535.  
  4536.  
  4537.  
  4538.  
  4539.  
  4540.  
  4541.  
  4542.  
  4543.  
  4544.  
  4545.  
  4546.  
  4547.  
  4548.  
  4549.                                                                    68
  4550.  
  4551.  
  4552.     E. Using Assembled Programs with Turbo Pascal:
  4553.  
  4554.        CHASM and Turbo Pascal work splendidly together, complementing
  4555.        each other's strong points.  You can use CHASM to provide new
  4556.        functions you wish Turbo had, or to fine tune a critical
  4557.        procedure for optimum speed.   CHASM itself is written in a
  4558.        combination of Turbo Pascal and CHASM.
  4559.  
  4560.        CHASM supports two techniques for producing machine language
  4561.        code for Turbo Pascal: external procedures or functions, and
  4562.        Turbo INLINE code.
  4563.  
  4564.     1. External Procedures and Functions:
  4565.  
  4566.        Turbo loads external procedures and functions within the same
  4567.        segment as the rest of your Pascal program.  You have no
  4568.        control of the exact load location (more on this later), but
  4569.        on the other hand, you don't have to worry about setting aside
  4570.        a special location for your procedures (as in BASIC).  Since
  4571.        your external procedure is loaded in the same segment as the
  4572.        Pascal code, it should be declared NEAR to CHASM:
  4573.  
  4574.          EXTERNAL PROC NEAR
  4575.                   ...           ;body of procedure
  4576.                   ...
  4577.                   ENDP
  4578.  
  4579.        Turbo passes parameters to your procedure/function via the
  4580.        stack.  To work effectively, a good grasp of the stack
  4581.        structure is critical.  Read the Turbo manual for information
  4582.        on internal data formats and parameter passing, to see just
  4583.        what to expect on the stack.  Also, remember that the stack
  4584.        grows down from the top of memory.
  4585.  
  4586.        If you're going to access the stack in your procedure, the
  4587.        first thing you should do is set up BP as a stack pointer.
  4588.        Since Turbo also uses BP, you have to save the current value
  4589.        first.  The obvious place to save it is on the stack...
  4590.  
  4591.           PUSH BP           ;save old BP
  4592.           MOV  BP, SP        ;and set up to indirectly address stack
  4593.  
  4594.  
  4595.  
  4596.  
  4597.  
  4598.  
  4599.  
  4600.  
  4601.  
  4602.  
  4603.  
  4604.  
  4605.  
  4606.  
  4607.  
  4608.  
  4609.  
  4610.  
  4611.  
  4612.  
  4613.  
  4614.  
  4615.                                                                    69
  4616.  
  4617.        You can now access the parameters on the stack using offsets
  4618.        off the BP register.  Note that since you PUSHed BP,
  4619.        everything is 2 bytes deeper onto the stack than what Turbo
  4620.        originally sent you.
  4621.  
  4622.        Here's an example.  Suppose you declare the following external
  4623.        function in Turbo:
  4624.  
  4625.           function Sum(x,y: int): int;
  4626.              external 'sum.com';
  4627.  
  4628.        After you've pushed BP, here's how the stack looks:
  4629.  
  4630.            stack contents           indirect address
  4631.         ----------------------------------------------
  4632.            <value of parameter y>        6[BP]
  4633.            <value of parameter x>        4[BP]
  4634.            <return address to Turbo>     2[BP]
  4635.            <old BP value>                 [BP]
  4636.  
  4637.        The indirect addresses go up two at a time, since each item on
  4638.        the stack is a word (two bytes) long. You can access the
  4639.        parameters using their indirect addresses. Here's the code for
  4640.        an external function to add two integer parameters:
  4641.  
  4642.        SUM  PROC NEAR
  4643.             PUSH BP          ;save old BP
  4644.             MOV  BP, SP      ;set up stack pointer
  4645.  
  4646.             MOV  AX,  4[BP]  ;get parameter x
  4647.             MOV  ADD, 6[BP]  ;add parameter y
  4648.                              ;leave sum in AX to return to Turbo
  4649.  
  4650.             POP  BP          ;restore old BP for Turbo
  4651.             RET  4           ;clear params off stack
  4652.             ENDP
  4653.  
  4654.        A more elegant way to access the parameters is by using a
  4655.        CHASM structure to define their offsets on the stack:
  4656.  
  4657.        STACK    STRUC
  4658.        OLDBP    DW   0000H
  4659.        RETADDR  DW   0000H
  4660.        XPARAM   DW   0000H
  4661.        YPARAM   DW   0000H
  4662.                 ENDSTRUC
  4663.  
  4664.  
  4665.  
  4666.  
  4667.  
  4668.  
  4669.  
  4670.  
  4671.  
  4672.  
  4673.  
  4674.  
  4675.  
  4676.  
  4677.  
  4678.  
  4679.  
  4680.  
  4681.                                                                    70
  4682.  
  4683.  
  4684.        With this structure added to the above example, you could
  4685.        access the parameters like this:
  4686.  
  4687.                 MOV  AX, XPARAM[BP]    ;get parameter X
  4688.  
  4689.        Functions return scalar results by having the value in AX upon
  4690.        return.  The function in the above example saves some time by
  4691.        calculating the value in AX in the first place.  Upon exit,
  4692.        the function POPs BP, to restore the value Turbo was using.
  4693.  
  4694.        Note the RET 4 in the example.  This returns to Turbo, while
  4695.        simultaneously POPing (and discarding) 4 bytes off the stack.
  4696.        This clears off the two parameters which Turbo passed.  If
  4697.        there were three parameters, you'd use a RET 6; if none, a
  4698.        simple RET would do. When Turbo receives control, it assumes
  4699.        that you've cleaned up the stack by removing all parameters.
  4700.        If you don't do this properly, a run-time error, or even a
  4701.        system crash will result.
  4702.  
  4703.        (Typical scenario:  Turbo tries to return from one of its own
  4704.        subroutines, thinking the top of the stack has the return
  4705.        address.  Unfortunately, the top is really an integer
  4706.        parameter, left over from your external function.  Turbo's
  4707.        RET sends control into some random area of memory, and boom -
  4708.        the system crashes.)
  4709.  
  4710.        It's easy to get confused about the exact contents of the
  4711.        stack.  If your procedure doesn't seem to be working right,
  4712.        the first thing to suspect is Turbo and you have different
  4713.        ideas about what's where on the stack.  A DEBUG session can
  4714.        usually straighten things out.
  4715.  
  4716.        Boolean functions constitute a special case which is poorly
  4717.        documented in the Turbo Pascal manual.  Boolean functions must
  4718.        return their result in two ways:
  4719.  
  4720.            1. by setting the zero flag (Z = false, NZ = true)
  4721.  
  4722.            2. and by returning either 0 (false) or 1 (true) in AX
  4723.  
  4724.        The first return method is assumed by Turbo if you use the
  4725.        function in a conditional statement, the second if you assign
  4726.        the value of the function to a variable.  You need to return
  4727.        the result both ways to cover all possible uses of your
  4728.        function.
  4729.  
  4730.  
  4731.  
  4732.  
  4733.  
  4734.  
  4735.  
  4736.  
  4737.  
  4738.  
  4739.  
  4740.  
  4741.  
  4742.  
  4743.  
  4744.  
  4745.  
  4746.  
  4747.                                                                    71
  4748.  
  4749.  
  4750.        When external functions are called, in addition to the normal
  4751.        parameters, Turbo passes something called the  "function
  4752.        result" on the stack.  When the result is a scalar type, this
  4753.        seems to be intended just as a local work area for you to use,
  4754.        since Turbo ignores any value you store there.  Like a
  4755.        parameter, the function result must be POPed off the stack
  4756.        when your return to Turbo. Unlike scalar parameters (which
  4757.        always occupy a word of stack memory, even if they are defined
  4758.        as byte), the function result is the exact length of the
  4759.        result type.  Thus for a boolean function, you have to POP off
  4760.        one extra byte above and beyond those for clearing off the
  4761.        parameters.
  4762.  
  4763.        A problem of addressability can crop up if your external
  4764.        procedure tries to maintain its own local variables and/or
  4765.        constants.  The problem is that you have no way of knowing
  4766.        just where Turbo is going to load your procedure within the
  4767.        shared segment.  As such, the address CHASM calculates for any
  4768.        memory locations are going to be offset from their real values
  4769.        by some unknown constant, the offset of the procedure within
  4770.        the shared segment.  This is called a relocation problem.
  4771.  
  4772.        Fortunately, there's a way around this problem, but it
  4773.        requires using a trick.  Your program has to figure out, *at
  4774.        run time*, just where it's located in memory.  If you could
  4775.        find out the offset of any known point in your procedure,
  4776.        you'd "have your bearings" so to speak, and could go on.
  4777.  
  4778.        The trick is as follows.  The 8088 CALL instruction pushes the
  4779.        address of the next instruction onto the stack, then branches
  4780.        to the location given in the CALL.  By performing a dummy
  4781.        CALL, then stealing the value off the stack, we have the
  4782.        location of a known spot in the procedure.   By subtracting
  4783.        the offset within the procedure of that known location, we get
  4784.        a pointer to the beginning of the procedure which can be used
  4785.        to access everything else.  Here's an example:
  4786.  
  4787.  
  4788.  
  4789.  
  4790.  
  4791.  
  4792.  
  4793.  
  4794.  
  4795.  
  4796.  
  4797.  
  4798.  
  4799.  
  4800.  
  4801.  
  4802.  
  4803.  
  4804.  
  4805.  
  4806.  
  4807.  
  4808.  
  4809.  
  4810.  
  4811.  
  4812.  
  4813.                                                                    72
  4814.  
  4815.        LOCAL  PROC NEAR
  4816.               PUSH BP                     ;set up to access stack
  4817.               MOV  BP, SP                 ; ditto
  4818.  
  4819.               CALL DUMMY                  ;establish addressability
  4820.        DUMMY  POP  BX                     ;  "           "
  4821.               SUB  BX, OFFSET(DUMMY)
  4822.  
  4823.               MOV  AX, 4[BP]                ;get parameter
  4824.               SEG  CS                       ;offset relative to CS
  4825.               ADD  OFFSET(TOTAL)[BX], AX    ;maintain running total
  4826.  
  4827.               POP  BP
  4828.               RET  2
  4829.        TOTAL  DW   0000H
  4830.               ENDP
  4831.  
  4832.        We use indirect addressing here.  After the funny business
  4833.        with the CALL, POP, SUB sequence, BX has a pointer to the
  4834.        beginning of the procedure.  Using indirect addressing, we
  4835.        take that pointer and add in the offset of the memory location
  4836.        we want to access.  In this example we're using a local
  4837.        variable to maintain a running total of the parameter which
  4838.        gets passed.
  4839.  
  4840.        Note the SEG CS just before the ADD which accesses the
  4841.        location TOTAL.  Since we found our bearings by stealing the
  4842.        address of a program instruction, our offset is known relative
  4843.        to the CS register, NOT the DS which is normally used to
  4844.        access data.  The SEG CS forces the 8088 to calculate the
  4845.        address using CS rather than the default DS register.  Every
  4846.        time you access a memory location within your procedure, you
  4847.        *MUST* do it relative to CS by using a segment override.
  4848.  
  4849.        Turbo requires that you preserve the values of the following
  4850.        registers:
  4851.  
  4852.             BP, CS, DS, SS
  4853.  
  4854.        If you want to use these registers in your routine, the
  4855.        easiest way to preserve them is to PUSH them onto the stack at
  4856.        the beginning of your routine, then POP them just before
  4857.        returning.  As near as I can tell, you can safely trash the
  4858.        other registers.
  4859.  
  4860.  
  4861.  
  4862.  
  4863.  
  4864.  
  4865.  
  4866.  
  4867.  
  4868.  
  4869.  
  4870.  
  4871.  
  4872.  
  4873.  
  4874.  
  4875.  
  4876.  
  4877.  
  4878.  
  4879.                                                                    73
  4880.  
  4881.     2. INLINE Code
  4882.  
  4883.        An alternative method of incorporating code into Turbo Pascal
  4884.        is through Turbo's inline statement.  The inline statement is
  4885.        intended for short routines or patches where you just give
  4886.        Turbo a list of numbers representing the code.  In addition to
  4887.        numbers, you can also include variable names in the inline
  4888.        list.  Turbo replaces them with their offsets at compile time.
  4889.  
  4890.        CHASM's INLINE pseudo-op is provided to facilitate producing
  4891.        Turbo inline code.  If you put an INLINE pseudo-op in your
  4892.        CHASM source file, rather than producing a normal object code
  4893.        file, CHASM produces a text file formatted to include in a
  4894.        Turbo inline statement.  For example:
  4895.  
  4896.            inline        ;shift to inline mode
  4897.            mov  ah, 0FH  ;call bios for video mode
  4898.            int  10H      ;  ditto
  4899.  
  4900.        produces the following object file:
  4901.  
  4902.                         {    inline       ;shift to inline mode    }
  4903.           $B4/$0F/      {    mov ah, 0FH  ;call bios for video mode}
  4904.           $CD/$10/      {    int 10H      ;  ditto                 }
  4905.  
  4906.        Object code is output in text form, as hex constants.  A
  4907.        comment with the source code for each line is also generated.
  4908.  
  4909.        The INLINE pseudo-op can appear anywhere in your source file,
  4910.        and it requires no operands.
  4911.  
  4912.        Object files produced from source files with an INLINE 
  4913.        pseudo-op are NOT executable!  They contain text suitable for
  4914.        inclusion in Turbo Pascal inline statements.  It's probably a
  4915.        good idea to override CHASM's default name for the object
  4916.        file, and specify something with an extension other than COM
  4917.        to prevent DOS from trying to run the program.
  4918.  
  4919.        Your inline code must preserve the BP, SP, DS and SS
  4920.        registers. If you need to modify these registers, you should
  4921.        PUSH the ones you need at the beginning of your code, and POP
  4922.        them at the end.
  4923.  
  4924.  
  4925.  
  4926.  
  4927.  
  4928.  
  4929.  
  4930.  
  4931.  
  4932.  
  4933.  
  4934.  
  4935.  
  4936.  
  4937.  
  4938.  
  4939.  
  4940.  
  4941.  
  4942.  
  4943.  
  4944.  
  4945.                                                                    74
  4946.  
  4947.        Turbo's inline statement allows you to insert variable names
  4948.        in with the list of numbers.  At compile time, Turbo will
  4949.        replace the name with the 16 bit offset of the variable in its
  4950.        native segment.  (See the Turbo Pascal manual for a discussion
  4951.        of internal data formats and the native segment of variables.)
  4952.  
  4953.        CHASM supports this capability with the TURBO() function.
  4954.        CHASM treats TURBO() as 16 bit immediate data during assembly.
  4955.        However, in place of the two bytes of data, CHASM outputs the
  4956.        function argument literally for Turbo to evaluate:
  4957.  
  4958.           inline
  4959.           mov   bl, turbo(flag)[bp]     ;local variable "flag"
  4960.           mov   ax, cs:[turbo(maxcode)] ;typed constant "maxcode"
  4961.           lds   si, turbo(y)[bp]        ;pointer to var parameter "y"
  4962.  
  4963.        produces:
  4964.  
  4965.                               {      inline                        }
  4966.           $8A/$9E/FLAG/       {      mov   bx, turbo(flag)[bp]     }
  4967.           $2E/$A1/MAXCODE/    {      mov   ax, cs:[turbo(maxcode)] }
  4968.           $C5/$B6/Y/          {      lds   si, turbo(y)[bp]        }
  4969.  
  4970.  
  4971.  
  4972.  
  4973.  
  4974.  
  4975.  
  4976.  
  4977.  
  4978.  
  4979.  
  4980.  
  4981.  
  4982.  
  4983.  
  4984.  
  4985.  
  4986.  
  4987.  
  4988.  
  4989.  
  4990.  
  4991.  
  4992.  
  4993.  
  4994.  
  4995.  
  4996.  
  4997.  
  4998.  
  4999.  
  5000.  
  5001.  
  5002.  
  5003.  
  5004.  
  5005.  
  5006.  
  5007.  
  5008.  
  5009.  
  5010.  
  5011.                                                                    75
  5012.  
  5013.     >>Notes for Those Upgrading to This Version of CHASM<<
  5014.  
  5015.     CHASM is not yet carved in stone - improvements and corrections
  5016.     are made fairly frequently, based on both my own experience in
  5017.     using the program, and the comments of outside users.  This
  5018.     section summarizes the changes which have been made since version
  5019.     1.2 was released.  Changes followed with an asterisk (*) denote
  5020.     modifications which could invalidate programs written under
  5021.     earlier versions of CHASM.
  5022.  
  5023.     Version   Notes
  5024.  
  5025.     4.07      Speed enhancement.  Intersegment JMP and CALL fixed.
  5026.               Expressions now allowed in the subset.
  5027.  
  5028.     4.06      Speed enhancement.  Turbo Pascal INLINE facility.
  5029.               /VIDEO configuration switch.  New conditionals: IFREG,
  5030.               IFREG8, IFREG16, IFSEGREG.  New pseudo-ops: INLINE,
  5031.               RADIX, CHKJMP, NOCHKJMP.  New function: TURBO(). Single
  5032.               quotes now allowed in strings (use two).  Obsolete
  5033.               COUNT, ENDC and DM pseudo-ops no longer supported. (*)
  5034.  
  5035.     4.05      Speed enhancement.  Characters now work in expressions.
  5036.               EJECT and EJECTIF appear *before* page breaks.  /DPAGE
  5037.               configuration switch.  Parameter collection on macro
  5038.               invocations now halts before comments.  SHL can now
  5039.               also be written as SAL.
  5040.  
  5041.     4.04      RET with displacement is now assembled correctly.
  5042.               Parser bug fixed which crashed on strings with '/'.
  5043.  
  5044.     4.03      Assembler variables.  Operand size incompatibility now
  5045.               reported. FSUB now assembles correctly.  Intermittent
  5046.               bug in expressions with forward references fixed.
  5047.               Indirect memory references with offsets and segment
  5048.               overides now assemble correctly.  Only the first
  5049.               occurrence of a phase error is now reported.
  5050.  
  5051.     4.02      DS storage assembly is now turned off during structure
  5052.               definitions.  Structures assemble faster. Intermittent
  5053.               problem with macro parameter expansion cleared up.
  5054.  
  5055.     4.01      8087 support.  WAITON and WAITOFF pseudo-ops. Internal
  5056.               labels for macros.  Corrects bug which caused crash on
  5057.               certain syntax errors.
  5058.  
  5059.  
  5060.  
  5061.  
  5062.  
  5063.  
  5064.  
  5065.  
  5066.  
  5067.  
  5068.  
  5069.  
  5070.  
  5071.  
  5072.  
  5073.  
  5074.  
  5075.  
  5076.  
  5077.                                                                    76
  5078.  
  5079.     4.00      Total rewrite in Turbo Pascal.  Subset replaces
  5080.               interpreted version as free distribution release.
  5081.               Faster assembly.  Symbol and macro tables now use all
  5082.               available memory.  Nested macros permitted.  Operand
  5083.               expressions. $ now returns location counter value.  New
  5084.               syntax for segment overrides.  Conditional pseudo-ops
  5085.               now evaluate operands.  Improved error and diagnostic
  5086.               messages.  DOS 2 or later now required (*). DOS 2 path
  5087.               support for files. Setting of DOS 2 ERRORLEVEL. EJECTIF
  5088.               pseudo-op added. New configuration switches: /DWIDTH,
  5089.               /FF /TIMER, /PATH. CHASM.CFG must now have only one
  5090.               switch per line (*).
  5091.  
  5092.     3.15      Macros added. New pseudo-ops: MACRO, ENDM, IFE, IFNE,
  5093.               IFB, IFNB, ELSE, ENDIF.
  5094.  
  5095.     3.14      Interpreted version frozen at version 2.13, further
  5096.               changes apply only to compiled version.  Memory
  5097.               requirement raised to 128K.  INCLUDE, STRUC, ENDSTRUC,
  5098.               DM, DW, LIST, NOLIST, COUNT and ENDC pseudo-ops added.
  5099.               Alternate mnemonics for the jump on condition
  5100.               instructions, and alternate syntax for the DIV and MUL
  5101.               instructions.  Binary numbers added.
  5102.  
  5103.     2.13      Assembly can now be aborted with the Esc key. Negative
  5104.               decimal numbers are working again.  Input lines now
  5105.               limited to 80 characters, and labels must begin with a
  5106.               non-numeral. (*)
  5107.  
  5108.     2.12      Listings can now be suppressed.  Error messages echoed to
  5109.               the console on non-screen listings. Expert mode added.
  5110.  
  5111.     2.11      Pagination improved.  Listings now time stamped. OFFSETs
  5112.               and word values now allowed in DB operand list.
  5113.  
  5114.     2.10      Equated symbols allowed in the DB operand list.  Status
  5115.               line improved.
  5116.  
  5117.     2.09      The first digit of hexadecimal constants must now be in
  5118.               the range 0-9. A leading zero is permitted on four digit
  5119.               hex constants, to allow fulfilling this condition. (*)
  5120.  
  5121.     2.08      Configuration process expanded.  CHASM now skips over
  5122.               perforations on printed listings.  EJECT pseudo-op added.
  5123.  
  5124.     2.07      Oops.  Configuration file now works as advertised.
  5125.  
  5126.  
  5127.  
  5128.  
  5129.  
  5130.  
  5131.  
  5132.  
  5133.  
  5134.  
  5135.  
  5136.  
  5137.  
  5138.  
  5139.  
  5140.  
  5141.  
  5142.  
  5143.                                                                    77
  5144.  
  5145.  
  5146.     2.06      CHASM now supports reverse long jumps.
  5147.  
  5148.     2.05      Compiled version released.  BSAVE pseudo-op.
  5149.               Configuration process simplified.
  5150.  
  5151.     2.04      TABs are now expanded and replaced with blanks, for
  5152.               compatibility with IBM text editors.
  5153.  
  5154.     2.03      Two bugs corrected.  The first bug involved incorrect
  5155.               assembly of indirect memory references which used a
  5156.               displacement in the range 128-255.  The second caused a
  5157.               program crash if a hex number longer than 4 digits was in
  5158.               found in the input file.
  5159.  
  5160.     2.01      COM2DATA utility added.
  5161.  
  5162.     2.00      Corrected a bug in the DS and DB pseudo-ops which caused
  5163.               the last label in a program to be redefined as a memory
  5164.               location.  Also, the TAB character was added as a new
  5165.               delimiter, and PRIMER.DOC was added to the CHASM package.
  5166.  
  5167.     1.9       The short jump is now represented with mnemonic JMPS, for
  5168.               compatibility with DEBUG version 1.1. (*)
  5169.  
  5170.     1.8       The operand type "character" was added as a new way to
  5171.               represent immediate data.
  5172.  
  5173.     1.7       The DS operator now works for blocks larger than 255
  5174.               bytes.  Also, the OFFSET function now works properly in
  5175.               the displacement field of an indirect memory reference.
  5176.  
  5177.     1.6       A revision of this document.  Some sections were improved
  5178.               slightly, and in response to user requests, a section on
  5179.               execution of assembled programs was added.
  5180.  
  5181.     1.5       Corrected an error which generated the message "Data too
  5182.               Long" if the value FFH was used as 8 bit immediate data.
  5183.  
  5184.     1.4       User interface improved.  CHASM now traps some common
  5185.               input errors such as misspelling a file name, or
  5186.               forgetting to turn on your printer.
  5187.  
  5188.     1.3       A speed enhancement.  Version 1.3 benchmarks about 5
  5189.               times faster than version 1.2.
  5190.  
  5191.  
  5192.  
  5193.  
  5194.  
  5195.  
  5196.  
  5197.  
  5198.  
  5199.  
  5200.  
  5201.  
  5202.  
  5203.  
  5204.  
  5205.  
  5206.  
  5207.  
  5208.  
  5209.                                                                    78
  5210.  
  5211.     >>Miscellaneous and A Word From Our Sponsor...<<
  5212.  
  5213.     A. Programming Notes:
  5214.  
  5215.        1. CHASM is written in a combination of Turbo Pascal and
  5216.           CHASM.  This is less incestuous than it sounds: the
  5217.           program was written in Turbo, then profiled to single
  5218.           out the critical routines.   The rate determining sections
  5219.           were rewritten in optimized assembly language, and
  5220.           assembled with the original Turbo Pascal version of CHASM.
  5221.           These routines were then incorporated as Turbo external
  5222.           procedures and functions in a new version of CHASM.
  5223.  
  5224.           The speed enhancements possible by "helping out" Turbo with
  5225.           CHASM can be quite dramatic.  Replacing four rate limiting
  5226.           routines out of the over two hundred routines in CHASM gave
  5227.           almost a four-fold speed increase!
  5228.  
  5229.           CHASM's source code is available to registered users by
  5230.           sending a formatted disk and stamped return mailer.  If you
  5231.           make any improvements, I'd like to hear about them for
  5232.           possible inclusion in future releases.
  5233.  
  5234.           Please note that although you can modify CHASM for your own
  5235.           use, under NO CIRCUMSTANCES may you distribute modified or
  5236.           translated versions, either in the public domain or for
  5237.           profit.
  5238.  
  5239.     B. Red Tape and Legal Nonsense:
  5240.  
  5241.        1. Disclaimer:
  5242.  
  5243.           CHASM is distributed as is, with no guarantee that it will
  5244.           work correctly in all situations.  In no event will the
  5245.           Author be liable for any damages, including lost profits,
  5246.           lost savings or other incidental or consequential damages
  5247.           arising out of the use of or inability to use these programs,
  5248.           even if the Author has been advised of the possibility of
  5249.           such damages, or for any claim by any other party.
  5250.  
  5251.           Despite the somewhat imposing statement above, it *is* my
  5252.           intention to fix any bugs which are brought to my attention.
  5253.           See the appendix on Bug Reporting for more details.
  5254.  
  5255.  
  5256.  
  5257.  
  5258.  
  5259.  
  5260.  
  5261.  
  5262.  
  5263.  
  5264.  
  5265.  
  5266.  
  5267.  
  5268.  
  5269.  
  5270.  
  5271.  
  5272.  
  5273.  
  5274.  
  5275.                                                                    79
  5276.  
  5277.        2. Copyright Information:
  5278.  
  5279.           The entire CHASM distribution package, consisting of the
  5280.           main program, documentation files, and various data and
  5281.           utility files, is copyright (c) 1983, 1984, 1985 and 1986
  5282.           by David Whitman.  The author reserves the exclusive right
  5283.           to distribute this package, or any part thereof, for
  5284.           profit. The name "CHASM (tm)", applied to a microcomputer
  5285.           assembler program, is a trademark of David Whitman.
  5286.  
  5287.           CHASM's Subset version and various subsidiary files may be
  5288.           copied freely by individuals for evaluation purposes.  It
  5289.           is expected that those who find the package useful will
  5290.           make a contribution directly to the author of the program.
  5291.           The Subset version identifies itself by displaying a banner
  5292.           page giving the author's address and inviting free copying.
  5293.           ONLY VERSIONS DISPLAYING THIS BANNER PAGE MAY BE COPIED.
  5294.  
  5295.           CHASM's Advanced version is only available to registered
  5296.           users who have made the $40 suggested payment.  Registered
  5297.           users may copy the program for backup purposes, but must
  5298.           restrict use of the program to either one user or one CPU,
  5299.           at their option.
  5300.  
  5301.           CHASM's source code is made available for educational
  5302.           purposes and to allow users to customize for their own
  5303.           personal use.  Under NO CIRCUMSTANCES may modified versions
  5304.           or translations into other computer languages be
  5305.           distributed, either in the public domain or for profit.
  5306.  
  5307.           User groups and clubs are authorized to distribute CHASM's
  5308.           Subset version under the following conditions:
  5309.  
  5310.           1.  No charge is made for the software or documentation.  A
  5311.               nominal distribution fee may be charged, provided that
  5312.               it is no more than $8 total.
  5313.  
  5314.           2.  Recipients are to be informed of the user-supported
  5315.               software concept, and encouraged to support it with
  5316.               their donations.
  5317.  
  5318.           3.  The program and documentation are not modified in ANY
  5319.               way, and are distributed together.
  5320.  
  5321.  
  5322.  
  5323.  
  5324.  
  5325.  
  5326.  
  5327.  
  5328.  
  5329.  
  5330.  
  5331.  
  5332.  
  5333.  
  5334.  
  5335.  
  5336.  
  5337.  
  5338.  
  5339.  
  5340.  
  5341.                                                                    80
  5342.  
  5343.           Interested manufacturers are invited to contact Whitman
  5344.           Software to discuss licensing CHASM for bundling with
  5345.           MS-DOS based computer systems. 
  5346.  
  5347.           Distribution of CHASM outside the United States is through
  5348.           licensed distributors, on a royalty basis.  Interested
  5349.           distributors are invited to contact Whitman Software. 
  5350.  
  5351.        3. Royalty Information: 
  5352.  
  5353.           No royalties are required to distribute programs produced
  5354.           using CHASM.  However, if you send me a copy of any major
  5355.           program you have produced using CHASM, I'll give you a free
  5356.           page of advertising in this document. 
  5357.  
  5358.        4. Educational Discount:
  5359.  
  5360.           Substantial discounts are available for multi-CPU licenses
  5361.           of CHASM's Advanced version to educational institutions.
  5362.           Contact Whitman Software for details.
  5363.  
  5364.     C. An Offer You Can't Refuse. 
  5365.  
  5366.        CHASM is User-Supported software, distributed under a
  5367.        modification of the FREEWARE (tm) marketing scheme developed by
  5368.        the late Andrew Fluegelman, whose inspiration and efforts are
  5369.        gratefully acknowledged.
  5370.  
  5371.        Anyone may obtain a free copy of CHASM's Subset version by
  5372.        sending a blank, formatted diskette to the author. An
  5373.        addressed, postage-paid return mailer must accompany the disk
  5374.        (no exceptions, please). 
  5375.  
  5376.        A copy of the program, with documentation, will be sent by
  5377.        return mail.  The program will carry a notice suggesting a
  5378.        payment to the program's author.  Making the payment
  5379.        is totally voluntary on the part of the user.  Regardless of
  5380.        whether a payment is made, the user is encouraged to
  5381.        share the program with others.  Payment for use is
  5382.        discretionary on the part of each subsequent user. 
  5383.  
  5384.  
  5385.  
  5386.  
  5387.  
  5388.  
  5389.  
  5390.  
  5391.  
  5392.  
  5393.  
  5394.  
  5395.  
  5396.  
  5397.  
  5398.  
  5399.  
  5400.  
  5401.  
  5402.  
  5403.  
  5404.  
  5405.  
  5406.  
  5407.                                                                    81
  5408.  
  5409.        The underlying philosophy here is based on three principles: 
  5410.  
  5411.        First, that the value and utility of software is best assessed
  5412.           by the user on his/her own system.  Only after using a
  5413.           program can one really determine whether it serves personal
  5414.           applications, needs, and tastes. 
  5415.  
  5416.        Second, that the creation of independent personal computer
  5417.           software can and should be supported by those who benefit
  5418.           from its use.  Remember the Tanstaafl principal:  There
  5419.           Ain't No Such Thing as a Free Lunch.
  5420.  
  5421.        Finally, that copying and networking of programs should be
  5422.           encouraged, rather than restricted.  The ease with which
  5423.           software can be distributed outside traditional commercial
  5424.           channels reflects the strength, rather than the weakness,
  5425.           of electronic information. 
  5426.  
  5427.       If you like this software, please help support it.  Your
  5428.       support can take three forms: 
  5429.  
  5430.       1. Become a registered user.  The suggested payment for
  5431.          registration is $40.
  5432.  
  5433.       2. Suggestions, comments, and bug reports.  Your comments will
  5434.          be taken seriously - user feedback was responsible for most
  5435.          of the changes listed in CHASM's revision history. 
  5436.  
  5437.       3. Spread the word.  Make copies of the Subset for friends.
  5438.          Write the editor of your favorite computer magazine.
  5439.          Astronomical advertising costs are one big reason that
  5440.          commercial software is so overpriced.  To continue offering
  5441.          CHASM this way, I need your help in letting other people
  5442.          know about CHASM. 
  5443.  
  5444.  
  5445.  
  5446.  
  5447.  
  5448.  
  5449.  
  5450.  
  5451.  
  5452.  
  5453.  
  5454.  
  5455.  
  5456.  
  5457.  
  5458.  
  5459.  
  5460.  
  5461.  
  5462.  
  5463.  
  5464.  
  5465.  
  5466.  
  5467.  
  5468.  
  5469.  
  5470.  
  5471.  
  5472.  
  5473.                                                                    82
  5474.  
  5475.       Those who make the $40 payment to become registered users
  5476.       receive the following benefits:
  5477.  
  5478.       1. An upgrade to the Advanced version of the program. The
  5479.          Advanced version executes twice as fast as the Subset and
  5480.          supports macros, conditional assembly and other features.
  5481.          An order form for the Advanced version is given at the end
  5482.          of this manual.
  5483.  
  5484.       2. User support, by phone or mail.  Support is only
  5485.          available to registered users.  Phone numbers and the
  5486.          address for help are given below.
  5487.  
  5488.       3. Notices announcing the release of significant upgrades.
  5489.  
  5490.     CHASM is copyrighted, and users are requested NOT to make copies
  5491.     of the Advanced version other than for their own use.  I am
  5492.     strongly opposed to copy protection, and would regret being
  5493.     forced to protect CHASM.  Please recognize the amount of time and
  5494.     money which went into producing CHASM, and respect the wishes of
  5495.     the author. 
  5496.  
  5497.           David Whitman
  5498.           P.O. Box 1157
  5499.           North Wales, PA 19454
  5500.  
  5501.           (215) 641-7522 (days)
  5502.           (215) 234-4084 (evenings)
  5503.  
  5504.  
  5505.  
  5506.  
  5507.  
  5508.  
  5509.  
  5510.  
  5511.  
  5512.  
  5513.  
  5514.  
  5515.  
  5516.  
  5517.  
  5518.  
  5519.  
  5520.  
  5521.  
  5522.  
  5523.  
  5524.  
  5525.  
  5526.  
  5527.  
  5528.  
  5529.  
  5530.  
  5531.  
  5532.  
  5533.  
  5534.  
  5535.  
  5536.  
  5537.  
  5538.  
  5539.                                                                    83
  5540.  
  5541.     Appendix A: 8088 Mnemonic List
  5542.  
  5543.     This appendix lists the mnemonics which CHASM will recognize,
  5544.     grouped roughly by function.  Consult "The 8086 Book" for
  5545.     definitions of these instructions, and for the operands each will
  5546.     accept.  Mnemonics marked with an asterisk (*) will accept a 'B'
  5547.     or 'W' suffix for ambiguous memory references.
  5548.  
  5549.     Arithmetic:
  5550.  
  5551.     AAA      AAD       AAM       AAS       ADC*      ADD*      CBW
  5552.     CWD      CMP*      CMPS*     DAA       DAS       DEC*      DIV*
  5553.     IDIV*    IMUL*     INC*      MUL*      NEG*      SBB*      SUB* 
  5554.  
  5555.     Data Movement:
  5556.  
  5557.     LAHF     LDS       LEA       LES       LODS*     MOV*     MOVS*
  5558.     POP      POPF      PUSH      PUSHF     SAHF      XCHG     XLAT
  5559.  
  5560.     Logical:
  5561.  
  5562.     AND*     NOT*      OR*       TEST*     XOR* 
  5563.  
  5564.     String Primitives:
  5565.  
  5566.     CMPS*    LODS*     MOVS*     SCAS*     STOS*
  5567.  
  5568.     Instruction Prefixes:
  5569.  
  5570.     LOCK     REP       REPE      REPNE     REPNZ     REPZ      SEG
  5571.  
  5572.     Program Counter Control: (unconditional)
  5573.  
  5574.     CALL     CALLN     CALLF     JMP       JMPF      JMPN      JMPS
  5575.     RET
  5576.  
  5577.     Program Counter Control: (conditional)
  5578.  
  5579.     JA       JAE      JB      JBE      JC        JCXZ       JE
  5580.     JG       JGE      JL      JLE      JNA       JNAE       JNB
  5581.     JNBE     JNC      JNE     JNG      JNGE      JNL        JNLE
  5582.     JNO      JNO      JNP     JNS      JNZ       JO         JP
  5583.     JPE      JPO      JS      JZ       LOOP      LOOPE      LOOPNE
  5584.     LOOPNZ   LOOPZ
  5585.  
  5586.  
  5587.  
  5588.  
  5589.  
  5590.  
  5591.  
  5592.  
  5593.  
  5594.  
  5595.  
  5596.  
  5597.  
  5598.  
  5599.  
  5600.  
  5601.  
  5602.  
  5603.  
  5604.  
  5605.                                                                    84
  5606.  
  5607.     Processor Control:
  5608.  
  5609.     CLC      CLD       CLI       CMC       HLT       NOP       STC
  5610.     STD      STI       WAIT
  5611.  
  5612.     I/O:
  5613.  
  5614.     IN       OUT
  5615.  
  5616.     Interrupt:
  5617.  
  5618.     INT      INTO      IRET
  5619.  
  5620.     Rotate and Shift:
  5621.  
  5622.     RCL*     RCR*      ROL*      ROR*      SAL*      SAR*      SHL*
  5623.     SHR*
  5624.  
  5625.  
  5626.  
  5627.  
  5628.  
  5629.  
  5630.  
  5631.  
  5632.  
  5633.  
  5634.  
  5635.  
  5636.  
  5637.  
  5638.  
  5639.  
  5640.  
  5641.  
  5642.  
  5643.  
  5644.  
  5645.  
  5646.  
  5647.  
  5648.  
  5649.  
  5650.  
  5651.  
  5652.  
  5653.  
  5654.  
  5655.  
  5656.  
  5657.  
  5658.  
  5659.  
  5660.  
  5661.  
  5662.  
  5663.  
  5664.  
  5665.  
  5666.  
  5667.  
  5668.  
  5669.  
  5670.  
  5671.                                                                    85
  5672.  
  5673.     Appendix B: 8087 Mnemonic List
  5674.  
  5675.     ===> Advanced version only.
  5676.  
  5677.     This appendix lists the 8087 mnemonics recognized by CHASM's
  5678.     Advanced version, grouped roughly by function.
  5679.  
  5680.     Arithmetic:
  5681.  
  5682.     FADD     FADDP    FCHS     FDIV     FDIVP     FDIVR    FDIVRP
  5683.     FIADD    FIDIV    FIDIVR   FIMUL    FISUB     FISUBR   FMUL
  5684.     FMULP    FPREM    FSUB     FSUBP    FSUBR     FSUBRP    
  5685.  
  5686.     Mathematical Functions:
  5687.  
  5688.     F2XM1    FABS     FPATAN   FPTAN    FRNDINT   FSCALE   FSQRT
  5689.     FXTRACT  FYL2X    FYL2XP1
  5690.  
  5691.     Data Movement:
  5692.  
  5693.     FBLD     FBSTP    FILD     FIST     FISTP     FLD      FLD1
  5694.     FLDL2E   FLDL2T   FLDLG2   FLDLN2   FLDPI     FLDZ     FST
  5695.     FSTP     FXCH
  5696.  
  5697.     Comparison:
  5698.  
  5699.     FCOM     FCOMP    FCOMPP   FICOM    FICOMP    FTST      FXAM
  5700.  
  5701.     Processor Control:
  5702.  
  5703.     FCLEX    FDECSTP  FDISI    FENI     FFREE     FINCSTP   FINIT
  5704.     FNCLEX   FNDISI   FNENI    FNINIT   FNOP      WAIT      
  5705.  
  5706.     Processor Status:
  5707.  
  5708.     FLDCW    FLDENV   FNSAVE   FNSTCW   FNSTENV   FNSTSW    FRSTOR
  5709.     FSAVE    FSTCW    FSTENV   FSTSW
  5710.  
  5711.  
  5712.  
  5713.  
  5714.  
  5715.  
  5716.  
  5717.  
  5718.  
  5719.  
  5720.  
  5721.  
  5722.  
  5723.  
  5724.  
  5725.  
  5726.  
  5727.  
  5728.  
  5729.  
  5730.  
  5731.  
  5732.  
  5733.  
  5734.  
  5735.  
  5736.  
  5737.                                                                    86
  5738.  
  5739.     Appendix C: Differences Between CHASM and That Other Assembler
  5740.  
  5741.     Virtually all magazine articles about assembly language
  5742.     programming on the IBM PC assume that the reader is using That
  5743.     Other Assembler - you know, the outrageously priced one.  This
  5744.     appendix will try to summarize the differences between the two
  5745.     programs.  Please note that I do not own a copy of That Other
  5746.     Assembler, and therefore this section is not complete, nor even
  5747.     guaranteed to be correct.  I continue to work on this section,
  5748.     and anyone with more experience is invited to make additions or
  5749.     corrections, so this section will continually improve with time.
  5750.  
  5751.     A. General Differences
  5752.  
  5753.     The biggest difference is philosophical.  The IBM assembler was
  5754.     designed for use by professional assembly language programmers,
  5755.     to write operating systems and other huge projects.  This is
  5756.     reflected in the large size and relative complexity of the macro
  5757.     assembler.
  5758.  
  5759.     On the other hand, CHASM was designed for use by beginners, to
  5760.     write relatively short programs.  This was done by leaving out
  5761.     some of the power offered by IBM's assembler, in exchange for
  5762.     simplicity and ease of use.  The main simplification involved
  5763.     producing object code in the COM format, rather than the EXE
  5764.     format chosen by IBM. There are two main consequences of this
  5765.     choice:
  5766.  
  5767.        1. You can't link routines assembled by CHASM to
  5768.           Microsoft languages. (Although you *can* include them in
  5769.           Turbo Pascal or BASIC programs.)
  5770.  
  5771.        2. Your program has to fit in one 64K segment.  If (shudder!)
  5772.           you want to write a 256K assembly language program, you're
  5773.           out of luck.
  5774.  
  5775.     Like Pascal, the IBM assembler is a strongly typed language.  By
  5776.     requiring you to specify the *type* of each memory location you
  5777.     will access in your program, the IBM assembler generally knows
  5778.     what size of memory operand you want.  If you don't like the
  5779.     declared size, you have to override the default with the PTR
  5780.     operator.  Thus, to loading the AL register from a location
  5781.     declared word is a syntax error, unless you specify BYTE PTR
  5782.     before the address.
  5783.  
  5784.  
  5785.  
  5786.  
  5787.  
  5788.  
  5789.  
  5790.  
  5791.  
  5792.  
  5793.  
  5794.  
  5795.  
  5796.  
  5797.  
  5798.  
  5799.  
  5800.  
  5801.  
  5802.  
  5803.                                                                    87
  5804.  
  5805.     In analogy to the C language, CHASM is weakly typed. CHASM is
  5806.     perfectly happy extracting a byte from where you originally set
  5807.     aside a word - CHASM can't tell the difference. In most cases,
  5808.     CHASM can tell what size you want from context:  for example, if
  5809.     you're using a word register, it *must* be a word memory access. On
  5810.     the other hand, for any access to memory which doesn't have a
  5811.     register as the other operand, you must add either a 'B' or a 'W'
  5812.     to the instruction mnemonic used by IBM.
  5813.  
  5814.     B. Miscellaneous Differences:
  5815.  
  5816.        1. Short Jumps:
  5817.  
  5818.           IBM uses the SHORT keyword, CHASM uses an 'S' suffix.
  5819.           Example:
  5820.  
  5821.           JMP   SHORT label    ;ibm
  5822.           JMPS  label          ;chasm
  5823.  
  5824.        2. Offset Function:
  5825.  
  5826.           Where IBM precedes an operand with the keyword OFFSET,
  5827.           CHASM has a *function* called OFFSET. CHASM requires
  5828.           parentheses around the operand. Example:
  5829.  
  5830.           MOV   AX, OFFSET FCB  ;ibm
  5831.           MOV   AX, OFFSET(FCB) ;chasm
  5832.  
  5833.        3. Declaring Storage:
  5834.  
  5835.           A.  If you don't care what value a memory location is
  5836.               initialized to, the IBM assembler allows you to specify
  5837.               '?' as its contents.  In CHASM, if you don't care what
  5838.               value the variable is initialized to, just put down a
  5839.               zero.  Example:
  5840.  
  5841.                  DB   ?      ;ibm
  5842.                  DB   0      ;chasm
  5843.  
  5844.  
  5845.  
  5846.  
  5847.  
  5848.  
  5849.  
  5850.  
  5851.  
  5852.  
  5853.  
  5854.  
  5855.  
  5856.  
  5857.  
  5858.  
  5859.  
  5860.  
  5861.  
  5862.  
  5863.  
  5864.  
  5865.  
  5866.  
  5867.  
  5868.  
  5869.                                                                    88
  5870.  
  5871.           B.  The IBM assembler allows the keyword DUP as an operand
  5872.               in storage declaring pseudo-ops.  This means to repeat
  5873.               the definition as many times as the number just before
  5874.               the DUP.  Example:
  5875.  
  5876.               DW   3 DUP(?)  ;ibm
  5877.               DW   0, 0, 0   ;chasm
  5878.  
  5879.     4. ASSUME Pseudo-op:
  5880.  
  5881.        IBM's ASSUME pseudo-op tells the assembler where the segment
  5882.        registers will be pointing.  CHASM always assumes that the CS,
  5883.        DS and SS registers point to the beginning of the code
  5884.        segment, and that the SS register has been set up to point to
  5885.        a valid stack area.  If you find an ASSUME pseudo-op with
  5886.        different assumptions for the CS, DS and ES registers you'll
  5887.        have to figure out the addresses for memory references in the DS
  5888.        and ES segments yourself.
  5889.  
  5890.     5. Segment Pseudo-op:
  5891.  
  5892.        This pseudo-op is used to set up multiple segments in the IBM
  5893.        assembler.  Since CHASM only allows one segment, there is no
  5894.        equivalent pseudo-op.  If there is only one segment definition
  5895.        in an IBM assembler program, everything is fine, just leave
  5896.        the pseudo-op out for CHASM.
  5897.  
  5898.        Often times the SEGMENT pseudo-op is used to provide
  5899.        addressing of an area in the BIOS, or perhaps the interrupt
  5900.        vector table at the beginning of memory.  For example, if a
  5901.        program needed to get at the BIOS data area, in the IBM
  5902.        assembler you would define a dummy segment with the same
  5903.        structure as that in the BIOS listing in Technical Reference:
  5904.  
  5905.          DATA          SEGMENT AT 40H
  5906.          RS232_BASE    DW    4 DUP(?)
  5907.          PRINTER_BASE  DW    4 DUP(?)
  5908.          EQUIP_FLAG    DW    ?
  5909.          MFG_TST       DB    ?
  5910.          MEMORY_SIZE   DW    ?
  5911.          IO_RAM_SIZE   DW    ?
  5912.  
  5913.        All this is really accomplishing is giving a name to some
  5914.        memory locations which are outside the actual program being
  5915.        written.
  5916.  
  5917.  
  5918.  
  5919.  
  5920.  
  5921.  
  5922.  
  5923.  
  5924.  
  5925.  
  5926.  
  5927.  
  5928.  
  5929.  
  5930.  
  5931.  
  5932.  
  5933.  
  5934.  
  5935.                                                                    89
  5936.  
  5937.        In CHASM, you can simulate the dummy segment using a
  5938.        structure.  This will generate a series of immediate operands
  5939.        whose values correspond to the offsets of the labels in the
  5940.        dummy segment.  You can then reference the locations by
  5941.        enclosing the label names in square brackets, to coerce from
  5942.        type immediate to type address.
  5943.  
  5944.          DUMMY         STRUC            ;simulate dummy segment
  5945.          RS232_BASE    DW    0, 0, 0, 0
  5946.          PRINTER_BASE  DW    0, 0, 0, 0
  5947.          EQUIP_FLAG    DW    0
  5948.          MFG_TST       DB    0
  5949.          MEMORY_SIZE   DW    0
  5950.          IO_RAM_SIZE   DW    0
  5951.                        ENDSTRUC
  5952.                        MOV AX, [EQUIP_FLAG]
  5953.  
  5954.     6. Labels:
  5955.  
  5956.        The macro assembler indicates a local label by appending a
  5957.        colon (:).  The colon does not become part of the label, and
  5958.        is not included when referencing the label.  CHASM's labels
  5959.        are all global, and although they may end with a colon, the
  5960.        colon will become part of the label itself, and must then be
  5961.        used when referencing the label.  Example:
  5962.  
  5963.        a2:   mov ax,cx      ;ibm
  5964.              jmp a2         ; "
  5965.  
  5966.        a2:   mov ax,cx      ;chasm
  5967.              jmp a2:        ;  "
  5968.  
  5969.        CHASM does provide support for local labels in macros.  See the
  5970.        discussion on internal labels in the macro section of this
  5971.        document.
  5972.  
  5973.     7. Entry Point:
  5974.  
  5975.        The macro assembler allows you to specify the point within
  5976.        your program where execution will begin.  A label is put
  5977.        on the entry point, then to indicate entry, the same label is
  5978.        placed on the "END" pseudo-op.  Since COM programs must always
  5979.        start at offset 100H, CHASM doesn't allow setting an entry
  5980.        point, or use the END pseudo-op.  
  5981.  
  5982.  
  5983.  
  5984.  
  5985.  
  5986.  
  5987.  
  5988.  
  5989.  
  5990.  
  5991.  
  5992.  
  5993.  
  5994.  
  5995.  
  5996.  
  5997.  
  5998.  
  5999.  
  6000.  
  6001.                                                                    90
  6002.  
  6003.     Appendix D: Description of Files
  6004.  
  6005.     Your CHASM distribution disk contains a number of files.  This
  6006.     appendix will give a brief statement of the purpose of each.
  6007.  
  6008.     FILE           DESCRIPTION
  6009.     ----------------------------------------------------------------
  6010.     CHASM.CFG       Sample configuration file, for IBM printer.
  6011.  
  6012.     CHASM.COM       The CHASM program (either subset or advanced)
  6013.  
  6014.     CHASMS.COM      This file may appear on the disk of advanced
  6015.                     version users.  It is the current subset version,
  6016.                     that can be shared with others.  Please rename it
  6017.                     CHASM.COM on their disk, to avoid confusion.
  6018.  
  6019.     CHASM.DOC       This document.
  6020.  
  6021.     EXAMPLE.ASM     Sample source file.
  6022.  
  6023.     COM2DATA.ASM    Source code for COM2DATA filter.
  6024.  
  6025.     COM2DATA.DOC    Documentation for COM2DATA.
  6026.  
  6027.     FREEWARE.DOC    References to other User Supported programs.
  6028.  
  6029.     PRIMER.DOC      Simple introduction to assembly language.
  6030.  
  6031.     Occasionally, various other sample source files for CHASM will be
  6032.     distributed.  These files will have extension ASM, and will be
  6033.     accompanied by a corresponding DOC file.
  6034.  
  6035.  
  6036.  
  6037.  
  6038.  
  6039.  
  6040.  
  6041.  
  6042.  
  6043.  
  6044.  
  6045.  
  6046.  
  6047.  
  6048.  
  6049.  
  6050.  
  6051.  
  6052.  
  6053.  
  6054.  
  6055.  
  6056.  
  6057.  
  6058.  
  6059.  
  6060.  
  6061.  
  6062.  
  6063.  
  6064.  
  6065.  
  6066.  
  6067.                                                                    91
  6068.  
  6069.     Appendix E: Bug Reporting Procedure
  6070.  
  6071.     Although each version of CHASM is tested extensively prior to
  6072.     release, any program of this magnitude is bound to contain a few
  6073.     bugs.  It is the intention of Whitman Software to correct any
  6074.     genuine problem which is reported.
  6075.  
  6076.     If you think you have found a bug in CHASM, please take the time
  6077.     to report it for correction.  Although any report is helpful,
  6078.     correction of the problem will be easiest if you provide the
  6079.     following:
  6080.  
  6081.        1. The version of CHASM you are using.  Your problem may have
  6082.           been fixed already!
  6083.  
  6084.        2. A brief description of what you believe the problem to be.
  6085.  
  6086.        3. A printed listing of a source file which manifests the
  6087.           problem.
  6088.  
  6089.           * DON'T send a 5,000 line program which has one
  6090.             manifestation of the bug!  Isolate the problem area, or
  6091.             write a short sample routine that demonstrates the bug.
  6092.  
  6093.     Unlike normal commercial software, where corrections are saved up
  6094.     for a major revision, bugs in CHASM are fixed as soon as reported,
  6095.     with a new version released almost immediately (which is why there
  6096.     are so many versions in CHASM's revision history).
  6097.  
  6098.                    =====> BONUS <======
  6099.  
  6100.     If you send a copy of your problem source file on disk, it will
  6101.     be returned with either a new, corrected version of CHASM, or
  6102.     with an explanation of what you were doing wrong to *think* you'd
  6103.     found a bug.
  6104.  
  6105.  
  6106.  
  6107.  
  6108.  
  6109.  
  6110.  
  6111.  
  6112.  
  6113.  
  6114.  
  6115.  
  6116.  
  6117.  
  6118.  
  6119.  
  6120.  
  6121.  
  6122.  
  6123.  
  6124.  
  6125.  
  6126.  
  6127.  
  6128.  
  6129.  
  6130.  
  6131.  
  6132.  
  6133.                                                                    92
  6134.  
  6135.     Appendix F: Using CHASM on "Compatible" Systems
  6136.  
  6137.     CHASM was written specifically for the IBM PC, but should
  6138.     function normally on true "compatibles".  This appendix is a new
  6139.     section to summarize compatibility data for various systems.
  6140.  
  6141.     Since CHASM version 4 is a totally new program, little
  6142.     compatibility data is currently available.  If you are using (or
  6143.     are unable to use...) CHASM on a non-IBM computer, please write
  6144.     with your experiences.  Does CHASM work correctly on your system?
  6145.     Are there specific problem areas?  Can they be worked around?
  6146.  
  6147.     If you are using a non-IBM system, I strongly recommend that at
  6148.     least to start out, you include the line:
  6149.  
  6150.           /VIDEO 2
  6151.  
  6152.     in your CHASM.CFG file (see the section on "Modifying CHASM's I/O
  6153.     Defaults" for a discussion of the CHASM.CFG file).  This will
  6154.     force CHASM to use BIOS calls to access your video screen.  By
  6155.     default, CHASM writes directly to the screen hardware for maximum
  6156.     speed.  Without this line, if your hardware is not *strictly* IBM
  6157.     compatible, CHASM's output could be invisible, or your system
  6158.     could even hang up and require re-booting.
  6159.  
  6160.     The following systems are reported to run CHASM version 4
  6161.     successfully:
  6162.  
  6163.            AT&T 6300
  6164.            Chameleon
  6165.            Columbia 1600-1
  6166.            Compaq, Compaq DeskPro, Compaq Plus
  6167.            Corona PC-2
  6168.            Heath 151
  6169.            IBM PC, XT, AT, 3270 PC, 3270 PC/G
  6170.            ITT XTRA
  6171.            Kaypro 16
  6172.            Leading Edge
  6173.            Mega XT
  6174.            PC Designs FD-1
  6175.            Sanyo 555
  6176.            Superior PC
  6177.            Tandy 1000, 2000
  6178.            Televideo 1605
  6179.            Zenith 150
  6180.  
  6181.  
  6182.  
  6183.  
  6184.  
  6185.  
  6186.  
  6187.  
  6188.  
  6189.  
  6190.  
  6191.  
  6192.  
  6193.  
  6194.  
  6195.  
  6196.  
  6197.  
  6198.  
  6199.                                                                    93
  6200.  
  6201.  
  6202.     The following systems have one or more problems:
  6203.  
  6204.     ================================================================
  6205.     Tandy 1200HD - CHASM crashes on some systems.  The problem seems
  6206.     to be related to the exact amount of free memory available on the
  6207.     system.  You can prevent the crash by slightly changing the
  6208.     amount of free memory, to either a higher or lower number.
  6209.     Probably the easiest way to do this is to change the number of
  6210.     disk buffers, or load an extra device driver such as ANSII.SYS.
  6211.     Call Whitman Software if you have trouble.
  6212.     ================================================================
  6213.     ================================================================
  6214.     IBM PCjr. - Several users report getting as far as the source file
  6215.     prompt, at which point the program crashes.  Several other users
  6216.     (invariably with more than 128K of memory) report that CHASM works
  6217.     fine.  The PCjr uses part of user memory for the screen buffer, and
  6218.     PCjr users probably need 192K to run CHASM.
  6219.     ================================================================
  6220.  
  6221.  
  6222.  
  6223.  
  6224.  
  6225.  
  6226.  
  6227.  
  6228.  
  6229.  
  6230.  
  6231.  
  6232.  
  6233.  
  6234.  
  6235.  
  6236.  
  6237.  
  6238.  
  6239.  
  6240.  
  6241.  
  6242.  
  6243.  
  6244.  
  6245.  
  6246.  
  6247.  
  6248.  
  6249.  
  6250.  
  6251.  
  6252.  
  6253.  
  6254.  
  6255.  
  6256.  
  6257.  
  6258.  
  6259.  
  6260.  
  6261.  
  6262.  
  6263.  
  6264.  
  6265.                                                                    94
  6266.  
  6267.           ********ADVANCED VERSION ORDER FORM********
  6268.  
  6269.     Please add me to the list of registered CHASM users, and send me
  6270.     an upgrade to Advanced CHASM.  I understand that CHASM is
  6271.     copyrighted, and agree not to distribute any unauthorized copies
  6272.     of this Advanced version.
  6273.  
  6274.     Note that version 4 requires DOS 2 (or later)
  6275.     and 128K of memory. (192K for PCjr)
  6276.  
  6277.     Computer Model: ____________________________________
  6278.  
  6279.     Diskette format:            Total Memory: _______K
  6280.  
  6281.        __ single sided/9 sector
  6282.  
  6283.        __ doubled sided/9 sector
  6284.  
  6285.     Check one:
  6286.  
  6287.            ___ I enclose a check for $40
  6288.  
  6289.            ___ I am a past customer.  The enclosed check brings my
  6290.                total payment up to $40.
  6291.  
  6292.  
  6293.     Where did you hear about CHASM? ________________________________
  6294.  
  6295.     Name:    _______________________________________________________
  6296.  
  6297.     Address: _______________________________________________________
  6298.  
  6299.     City, State, Zip: ______________________________________________
  6300.  
  6301.  
  6302.     ================================================================
  6303.          Send order form and check to:
  6304.  
  6305.               Whitman Software
  6306.               P.O. Box 1157
  6307.               North Wales, PA 19454
  6308.  
  6309.  
  6310.  
  6311.  
  6312.  
  6313.  
  6314.  
  6315.  
  6316.  
  6317.  
  6318.  
  6319.  
  6320.  
  6321.  
  6322.  
  6323.  
  6324.  
  6325.  
  6326.  
  6327.  
  6328.  
  6329.  
  6330.  
  6331.                                                                    95
  6332.  
  6333.       ==============PRINTER ENHANCEMENT===================
  6334.  
  6335.  
  6336.     Michael Hoyt, of Soft and Friendly Software, has produced a set
  6337.     of printer enhancement programs using CHASM, which is sold under
  6338.     the name Prowriter Utilities.  The package supports the following
  6339.     printers:
  6340.  
  6341.         NEC 8023A-C
  6342.         Prowriter I  (C. Itoh 8510)
  6343.         Prowriter II (C. Itoh 1550)
  6344.  
  6345.     The package contains three programs:
  6346.  
  6347.         PRINT_CHARACTERS
  6348.         PRINT_SCREEN
  6349.         PRINT_SET
  6350.  
  6351.     Once PRINT_CHARACTERS is run, it attaches itself to DOS, and
  6352.     makes your printer have exactly the same character set as your
  6353.     video monitor.  The conversion is very professionally done.
  6354.     Particularly impressive are the line drawing characters, which
  6355.     actually form connected lines, both horizontally and vertically.
  6356.  
  6357.     As if this wasn't enough, PRINT_CHARACTERS adds italics
  6358.     capability as well.  The italics make very effective emphasis in
  6359.     documents and letters, and look really good.
  6360.  
  6361.     PRINT_SCREEN is a graphics screen dump, activated by the normal
  6362.     Shift/PrtSc sequence.  Several options are available which trade
  6363.     off speed and print quality.  Since I have the mono card, I
  6364.     haven't tried PRINT_SCREEN, but Michael sent me a sample printout
  6365.     which looked quite nice.
  6366.  
  6367.     PRINT_SET is a menu-driven program to turn on and off the various
  6368.     special printing modes supported by these printers.  A simple but
  6369.     effective program.
  6370.  
  6371.     I've been using this package with my NEC 8023 for a few months
  6372.     now, and I like them quite a bit.  To get a copy, send $35 to:
  6373.  
  6374.         Soft and Friendly
  6375.         RR 2 Box 65
  6376.         Solsberry, IN 47459
  6377.  
  6378.  
  6379.  
  6380.  
  6381.  
  6382.  
  6383.  
  6384.  
  6385.  
  6386.  
  6387.  
  6388.  
  6389.  
  6390.  
  6391.  
  6392.  
  6393.  
  6394.  
  6395.  
  6396.  
  6397.                                                                    96
  6398.  
  6399.  
  6400.  
  6401.          ================= NEW PRODUCT ==================
  6402.  
  6403.     If you use the IBM/Microsoft BASIC compiler, chances are your
  6404.     programs are bigger and slower than they have to be.  If all
  6405.     unreferenced line numbers are removed from your source program,
  6406.     and the /N switch is used, BASCOM will "optimize" your program.
  6407.     The result is tighter, more efficient code.
  6408.  
  6409.     NUMZAP is a utility which carefully scans your source file, and
  6410.     deletes all the non-essential line numbers.  Performing this task
  6411.     by hand would be prohibitively time consuming and you'd probably
  6412.     introduce errors into your program in the process.  NUMZAP will
  6413.     do the job in minutes, 100% error free.
  6414.  
  6415.     The old BASIC version of CHASM was passed through NUMZAP, and the
  6416.     resulting compiled code shrank by a factor of 10% (!).  That 10%
  6417.     reduction could make the difference between your program running
  6418.     in 64K, or having users with minimal systems get "Out of Memory"
  6419.     messages just before your program crashes.
  6420.  
  6421.     An added advantage to using NUMZAP is that bigger programs can be
  6422.     compiled.  You may not be aware that there is a limit on the size
  6423.     of program which the compiler can handle.  BASCOM uses up space
  6424.     remembering the offset of each line number in your program. If
  6425.     you have too many numbered lines, BASCOM will run out of room and
  6426.     you'll get a unending series of "TC" (Too Complex) error
  6427.     messages.  By eliminating the unneeded line numbers, you give
  6428.     BASCOM more elbow room.  The free space available to compile
  6429.     CHASM increased 27% (!) after using NUMZAP.
  6430.  
  6431.     NUMZAP is available under the standard FREEWARE deal - just send
  6432.     a formatted disk and self-addressed, stamped return mailer to:
  6433.  
  6434.                 David Whitman
  6435.                 P.O. Box 1157
  6436.                 North Wales, PA 19454
  6437.  
  6438.     Be sure to specify that you are interested in NUMZAP.  If you
  6439.     like the program, a donation of $15 is suggested.
  6440.  
  6441.  
  6442.  
  6443.  
  6444.  
  6445.  
  6446.  
  6447.  
  6448.  
  6449.  
  6450.  
  6451.  
  6452.  
  6453.  
  6454.  
  6455.  
  6456.  
  6457.  
  6458.  
  6459.  
  6460.  
  6461.  
  6462.  
  6463.